#include <fstream>

#include "vtr_log.h"
#include "vtr_assert.h"
#include "vtr_math.h"

#include "globals.h"
#include "timing_util.h"
#include "timing_info.h"

double sec_to_nanosec(double seconds) {
    return 1e9 * seconds;
}

double sec_to_mhz(double seconds) {
    return (1. / seconds) / 1e6;
}

/*
 * Setup-time related
 */
tatum::TimingPathInfo find_longest_critical_path_delay(const tatum::TimingConstraints& constraints, const tatum::SetupTimingAnalyzer& setup_analyzer) {
    tatum::TimingPathInfo crit_path_info;

    auto& timing_ctx = g_vpr_ctx.timing();

    auto cpds = tatum::find_critical_paths(*timing_ctx.graph, constraints, setup_analyzer);

    //Record the maximum critical path accross all domain pairs
    for (const auto& path_info : cpds) {
        if (crit_path_info.delay() < path_info.delay() || std::isnan(crit_path_info.delay())) {
            crit_path_info = path_info;
        }
    }

    return crit_path_info;
}

tatum::TimingPathInfo find_least_slack_critical_path_delay(const tatum::TimingConstraints& constraints, const tatum::SetupTimingAnalyzer& setup_analyzer) {
    tatum::TimingPathInfo crit_path_info;

    auto& timing_ctx = g_vpr_ctx.timing();

    auto cpds = tatum::find_critical_paths(*timing_ctx.graph, constraints, setup_analyzer);

    //Record the maximum critical path accross all domain pairs
    for (const auto& path_info : cpds) {
        if (path_info.slack() < crit_path_info.slack() || std::isnan(crit_path_info.slack())) {
            crit_path_info = path_info;
        }
    }

    return crit_path_info;
}

float find_setup_total_negative_slack(const tatum::SetupTimingAnalyzer& setup_analyzer) {
    auto& timing_ctx = g_vpr_ctx.timing();

    float tns = 0.;
    for (tatum::NodeId node : timing_ctx.graph->logical_outputs()) {
        for (tatum::TimingTag tag : setup_analyzer.setup_slacks(node)) {
            float slack = tag.time().value();
            if (slack < 0.) {
                tns += slack;
            }
        }
    }
    return tns;
}

float find_setup_worst_negative_slack(const tatum::SetupTimingAnalyzer& setup_analyzer) {
    auto& timing_ctx = g_vpr_ctx.timing();

    float wns = 0.;
    for (tatum::NodeId node : timing_ctx.graph->logical_outputs()) {
        for (tatum::TimingTag tag : setup_analyzer.setup_slacks(node)) {
            float slack = tag.time().value();

            if (slack < 0.) {
                wns = std::min(wns, slack);
            }
        }
    }
    return wns;
}

float find_node_setup_slack(const tatum::SetupTimingAnalyzer& setup_analyzer, tatum::NodeId node, tatum::DomainId launch_domain, tatum::DomainId capture_domain) {
    for (const auto& tag : setup_analyzer.setup_slacks(node)) {
        if (tag.launch_clock_domain() == launch_domain &&
                tag.capture_clock_domain() == capture_domain) {
            return tag.time().value();
        }
    }

    return NAN;
}

std::vector<HistogramBucket> create_setup_slack_histogram(const tatum::SetupTimingAnalyzer& setup_analyzer, size_t num_bins) {
    auto& timing_ctx = g_vpr_ctx.timing();

    std::vector<HistogramBucket> histogram;

    //Find the min and max slacks
    float min_slack = std::numeric_limits<float>::infinity();
    float max_slack = -std::numeric_limits<float>::infinity();
    for (tatum::NodeId node : timing_ctx.graph->logical_outputs()) {
        for (tatum::TimingTag tag : setup_analyzer.setup_slacks(node)) {
            float slack = tag.time().value();

            min_slack = std::min(min_slack, slack);
            max_slack = std::max(max_slack, slack);
        }
    }

    //Determine the bin size
    float range = max_slack - min_slack;
    float bin_size = range / num_bins;

    //Create the buckets
    float bucket_min = min_slack;
    for (size_t ibucket = 0; ibucket < num_bins; ++ibucket) {
        float bucket_max = bucket_min + bin_size;

        histogram.emplace_back(bucket_min, bucket_max);

        bucket_min = bucket_max;
    }

    //To avoid round-off errors we force the max value of the last bucket equal to the max slack
    histogram[histogram.size() - 1].max_value = max_slack;

    //Count the slacks into the buckets
    auto comp = [](const HistogramBucket& bucket, float slack) {
        return bucket.max_value < slack;
    };

    for (tatum::NodeId node : timing_ctx.graph->logical_outputs()) {
        for (tatum::TimingTag tag : setup_analyzer.setup_slacks(node)) {
            float slack = tag.time().value();

            //Find the bucket who's max is less than the current slack

            auto iter = std::lower_bound(histogram.begin(), histogram.end(), slack, comp);
            VTR_ASSERT(iter != histogram.end());

            iter->count++;
        }
    }

    return histogram;
}

void print_setup_timing_summary(const tatum::TimingConstraints& constraints, const tatum::SetupTimingAnalyzer& setup_analyzer) {
    auto& timing_ctx = g_vpr_ctx.timing();

    auto crit_paths = tatum::find_critical_paths(*timing_ctx.graph, constraints, setup_analyzer);

    auto least_slack_cpd = find_least_slack_critical_path_delay(constraints, setup_analyzer);
    VTR_LOG("Final critical path: %g ns", sec_to_nanosec(least_slack_cpd.delay()));

    if (crit_paths.size() == 1) {
        //Fmax is only meaningful for a single-clock circuit
        VTR_LOG(", Fmax: %g MHz", sec_to_mhz(least_slack_cpd.delay()));
    }
    VTR_LOG("\n");

    VTR_LOG("Setup Worst Negative Slack (sWNS): %g ns\n", sec_to_nanosec(find_setup_worst_negative_slack(setup_analyzer)));
    VTR_LOG("Setup Total Negative Slack (sTNS): %g ns\n", sec_to_nanosec(find_setup_total_negative_slack(setup_analyzer)));
    VTR_LOG("\n");

    VTR_LOG("Setup slack histogram:\n");
    print_histogram(create_setup_slack_histogram(setup_analyzer));


    if (crit_paths.size() > 1) {
        //Multi-clock
        VTR_LOG("\n");

        //Periods per constraint
        VTR_LOG("Intra-domain critical path delays (CPDs):\n");
        for (const auto& path : crit_paths) {
            if (path.launch_domain() == path.capture_domain()) {
                VTR_LOG("  %s to %s CPD: %g ns (%g MHz)\n",
                        constraints.clock_domain_name(path.launch_domain()).c_str(),
                        constraints.clock_domain_name(path.capture_domain()).c_str(),
                        sec_to_nanosec(path.delay()),
                        sec_to_mhz(path.delay()));
            }
        }
        VTR_LOG("\n");

        VTR_LOG("Inter-domain critical path delays (CPDs):\n");
        for (const auto& path : crit_paths) {
            if (path.launch_domain() != path.capture_domain()) {
                VTR_LOG("  %s to %s CPD: %g ns (%g MHz)\n",
                        constraints.clock_domain_name(path.launch_domain()).c_str(),
                        constraints.clock_domain_name(path.capture_domain()).c_str(),
                        sec_to_nanosec(path.delay()),
                        sec_to_mhz(path.delay()));
            }
        }
        VTR_LOG("\n");

        //Slack per constraint
        VTR_LOG("Intra-domain worst setup slacks per constraint:\n");
        for (const auto& path : crit_paths) {
            if (path.launch_domain() == path.capture_domain()) {
                VTR_LOG("  %s to %s worst setup slack: %g ns\n",
                        constraints.clock_domain_name(path.launch_domain()).c_str(),
                        constraints.clock_domain_name(path.capture_domain()).c_str(),
                        sec_to_nanosec(path.slack()));
            }
        }
        VTR_LOG("\n");

        VTR_LOG("Inter-domain worst setup slacks per constraint:\n");
        for (const auto& path : crit_paths) {
            if (path.launch_domain() != path.capture_domain()) {
                VTR_LOG("  %s to %s worst setup slack: %g ns\n",
                        constraints.clock_domain_name(path.launch_domain()).c_str(),
                        constraints.clock_domain_name(path.capture_domain()).c_str(),
                        sec_to_nanosec(path.slack()));
            }
        }
    }

    //Calculate the intra-domain (i.e. same launch and capture domain) non-virtual geomean, and fanout-weighted periods
    if (crit_paths.size() > 1) {
        std::vector<double> intra_domain_cpds;
        std::vector<double> fanout_weighted_intra_domain_cpds;
        double total_intra_domain_fanout = 0.;
        auto clock_fanouts = count_clock_fanouts(*timing_ctx.graph, setup_analyzer);
        for (const auto& path : crit_paths) {
            if (path.launch_domain() == path.capture_domain() && !constraints.is_virtual_clock(path.launch_domain())) {
                intra_domain_cpds.push_back(path.delay());

                auto iter = clock_fanouts.find(path.launch_domain());
                VTR_ASSERT(iter != clock_fanouts.end());
                double fanout = iter->second;

                fanout_weighted_intra_domain_cpds.push_back(path.delay() * fanout);
                total_intra_domain_fanout += fanout;
            }
        }

        //Print multi-clock geomeans
        if (intra_domain_cpds.size() > 0) {
            VTR_LOG("\n");
            double geomean_intra_domain_cpd = vtr::geomean(intra_domain_cpds.begin(), intra_domain_cpds.end());
            VTR_LOG("Geometric mean non-virtual intra-domain period: %g ns (%g MHz)\n",
                    sec_to_nanosec(geomean_intra_domain_cpd),
                    sec_to_mhz(geomean_intra_domain_cpd));

            //Normalize weighted fanouts by total fanouts
            for (auto& weighted_cpd : fanout_weighted_intra_domain_cpds) {
                weighted_cpd /= total_intra_domain_fanout;
            }
            double fanout_weighted_geomean_intra_domain_cpd = vtr::geomean(fanout_weighted_intra_domain_cpds.begin(),
                    fanout_weighted_intra_domain_cpds.end());
            VTR_LOG("Fanout-weighted geomean non-virtual intra-domain period: %g ns (%g MHz)\n",
                    sec_to_nanosec(fanout_weighted_geomean_intra_domain_cpd),
                    sec_to_mhz(fanout_weighted_geomean_intra_domain_cpd));
        }
    }
    VTR_LOG("\n");
}

/*
 * Hold-time related statistics
 */
float find_hold_total_negative_slack(const tatum::HoldTimingAnalyzer& hold_analyzer) {
    auto& timing_ctx = g_vpr_ctx.timing();

    float tns = 0.;
    for (tatum::NodeId node : timing_ctx.graph->logical_outputs()) {
        for (tatum::TimingTag tag : hold_analyzer.hold_slacks(node)) {
            float slack = tag.time().value();
            if (slack < 0.) {
                tns += slack;
            }
        }
    }
    return tns;

}

tatum::NodeId find_origin_node_for_hold_slack(const tatum::TimingTags::tag_range arrival_tags,
        const tatum::TimingTags::tag_range required_tags, float slack) {
    /*Given the slack, arrival, and required tags of a certain timing node,
     its origin node is found*/
    for (tatum::TimingTag arrival_tag : arrival_tags) {
        for (tatum::TimingTag required_tag : required_tags) {
            if (arrival_tag.time().value() - required_tag.time().value() == slack) {
                tatum::NodeId origin_node = arrival_tag.origin_node();
                VTR_ASSERT(origin_node);
                return origin_node;
            }
        }
    }
    return tatum::NodeId::INVALID();
}

float find_total_negative_slack_within_clb_blocks(const tatum::HoldTimingAnalyzer& hold_analyzer) {
    /*Some negative slack are found within short paths in clb blocks. This cannot be optimized
     by the router. This function is used to measure the effectiveness of the router's
     hold time optimizer*/
    auto& timing_ctx = g_vpr_ctx.timing();
    auto& atom_ctx = g_vpr_ctx.atom();

    float slack_in_block = 0;
    for (tatum::NodeId node : timing_ctx.graph->logical_outputs()) {
        for (tatum::TimingTag tag : hold_analyzer.hold_slacks(node)) {
            float slack = tag.time().value();

            auto arrival_tags = hold_analyzer.hold_tags(node, tatum::TagType::DATA_ARRIVAL);
            auto required_tags = hold_analyzer.hold_tags(node, tatum::TagType::DATA_REQUIRED);
            tatum::NodeId origin_node = find_origin_node_for_hold_slack(arrival_tags, required_tags, slack);

            VTR_ASSERT(origin_node);

            /*Retrieve the source and sink clb blocks corresponding to these timing nodes*/
            AtomPinId origin_pin = atom_ctx.lookup.tnode_atom_pin(origin_node);
            AtomPinId pin = atom_ctx.lookup.tnode_atom_pin(node);
            VTR_ASSERT(origin_pin);
            VTR_ASSERT(pin);

            AtomBlockId atom_src_block = atom_ctx.nlist.pin_block(origin_pin);
            AtomBlockId atom_sink_block = atom_ctx.nlist.pin_block(pin);

            ClusterBlockId clb_src_block = atom_ctx.lookup.atom_clb(atom_src_block);
            VTR_ASSERT(clb_src_block);
			ClusterBlockId clb_sink_block = atom_ctx.lookup.atom_clb(atom_sink_block);
            VTR_ASSERT(clb_sink_block);

            const t_pb_graph_pin* sink_gpin = atom_ctx.lookup.atom_pin_pb_graph_pin(pin);
            VTR_ASSERT(sink_gpin);

            int sink_pb_route_id = sink_gpin->pin_count_in_cluster;
			ClusterNetId net_id;
			int sink_block_pin_index, sink_net_pin_index;
            std::tie(net_id, sink_block_pin_index, sink_net_pin_index) = find_pb_route_clb_input_net_pin(clb_sink_block, sink_pb_route_id);

            if(net_id == ClusterNetId::INVALID() && sink_block_pin_index == -1 && sink_net_pin_index == -1) {
                /*Does not go out of the cluster*/
                if (clb_sink_block == clb_src_block) {
                    if (slack < 0.) {
                        slack_in_block += slack;
                    }
                }
            }
        }
    }
    return slack_in_block;
}

float find_hold_worst_negative_slack(const tatum::HoldTimingAnalyzer& hold_analyzer) {
    auto& timing_ctx = g_vpr_ctx.timing();

    float wns = 0.;
    for (tatum::NodeId node : timing_ctx.graph->logical_outputs()) {
        for (tatum::TimingTag tag : hold_analyzer.hold_slacks(node)) {
            float slack = tag.time().value();

            if (slack < 0.) {
                wns = std::min(wns, slack);
            }
        }
    }
    return wns;
}

float find_hold_worst_slack(const tatum::HoldTimingAnalyzer& hold_analyzer, const tatum::DomainId launch, const tatum::DomainId capture) {
    auto& timing_ctx = g_vpr_ctx.timing();

    float worst_slack = std::numeric_limits<float>::infinity();
    for (tatum::NodeId node : timing_ctx.graph->logical_outputs()) {
        for (tatum::TimingTag tag : hold_analyzer.hold_slacks(node)) {
            if (tag.launch_clock_domain() == launch && tag.capture_clock_domain() == capture) {
                float slack = tag.time().value();

                worst_slack = std::min(worst_slack, slack);
            }
        }
    }
    return worst_slack;
}

std::vector<HistogramBucket> create_hold_slack_histogram(const tatum::HoldTimingAnalyzer& hold_analyzer, size_t num_bins) {
    auto& timing_ctx = g_vpr_ctx.timing();

    std::vector<HistogramBucket> histogram;

    //Find the min and max slacks
    float min_slack = std::numeric_limits<float>::infinity();
    float max_slack = -std::numeric_limits<float>::infinity();
    for (tatum::NodeId node : timing_ctx.graph->logical_outputs()) {
        for (tatum::TimingTag tag : hold_analyzer.hold_slacks(node)) {
            float slack = tag.time().value();

            min_slack = std::min(min_slack, slack);
            max_slack = std::max(max_slack, slack);
        }
    }

    //Determine the bin size
    float range = max_slack - min_slack;
    float bin_size = range / num_bins;

    //Create the buckets
    float bucket_min = min_slack;
    for (size_t ibucket = 0; ibucket < num_bins; ++ibucket) {
        float bucket_max = bucket_min + bin_size;

        histogram.emplace_back(bucket_min, bucket_max);

        bucket_min = bucket_max;
    }

    //To avoid round-off errors we force the max value of the last bucket equal to the max slack
    histogram[histogram.size() - 1].max_value = max_slack;

    //Count the slacks into the buckets
    auto comp = [](const HistogramBucket& bucket, float slack) {
        return bucket.max_value < slack;
    };

    for (tatum::NodeId node : timing_ctx.graph->logical_outputs()) {
        for (tatum::TimingTag tag : hold_analyzer.hold_slacks(node)) {
            float slack = tag.time().value();

            //Find the bucket who's max is less than the current slack
            auto iter = std::lower_bound(histogram.begin(), histogram.end(), slack, comp);
            VTR_ASSERT(iter != histogram.end());

            //Add to bucket
            iter->count++;
        }
    }

    return histogram;
}

void print_hold_timing_summary(const tatum::TimingConstraints& constraints, const tatum::HoldTimingAnalyzer& hold_analyzer) {
    VTR_LOG("Hold Worst Negative Slack (hWNS): %g ns\n", sec_to_nanosec(find_hold_worst_negative_slack(hold_analyzer)));
    VTR_LOG("Hold Total Negative Slack (hTNS): %g ns\n", sec_to_nanosec(find_hold_total_negative_slack(hold_analyzer)));
    /*For testing*/
    //VTR_LOG("Hold Total Negative Slack within clbs: %g ns\n", sec_to_nanosec(find_total_negative_slack_within_clb_blocks(hold_analyzer)));
    VTR_LOG("\n");

    VTR_LOG("Hold slack histogram:\n");
    print_histogram(create_hold_slack_histogram(hold_analyzer));

    if (constraints.clock_domains().size() > 1) {
        //Multi-clock
        VTR_LOG("\n");

        //Slack per constraint
        VTR_LOG("Intra-domain worst hold slacks per constraint:\n");
        for (const auto& domain : constraints.clock_domains()) {
            float worst_slack = find_hold_worst_slack(hold_analyzer, domain, domain);

            if (worst_slack == std::numeric_limits<float>::infinity()) continue; //No path


            VTR_LOG("  %s to %s worst hold slack: %g ns\n",
                    constraints.clock_domain_name(domain).c_str(),
                    constraints.clock_domain_name(domain).c_str(),
                    sec_to_nanosec(worst_slack));
        }
        VTR_LOG("\n");

        VTR_LOG("Inter-domain worst hold slacks per constraint:\n");
        for (const auto& launch_domain : constraints.clock_domains()) {
            for (const auto& capture_domain : constraints.clock_domains()) {
                if (launch_domain != capture_domain) {
                    float worst_slack = find_hold_worst_slack(hold_analyzer, launch_domain, capture_domain);

                    if (worst_slack == std::numeric_limits<float>::infinity()) continue; //No path

                    VTR_LOG("  %s to %s worst hold slack: %g ns\n",
                            constraints.clock_domain_name(launch_domain).c_str(),
                            constraints.clock_domain_name(capture_domain).c_str(),
                            sec_to_nanosec(worst_slack));
                }
            }
        }
    }
    VTR_LOG("\n");
}

/*
 * General utilities
 */
std::map<tatum::DomainId, size_t> count_clock_fanouts(const tatum::TimingGraph& timing_graph, const tatum::SetupTimingAnalyzer& setup_analyzer) {
    std::map<tatum::DomainId, size_t> fanouts;
    for (tatum::NodeId node : timing_graph.nodes()) {

        tatum::NodeType type = timing_graph.node_type(node);
        if (type == tatum::NodeType::SOURCE || type == tatum::NodeType::SINK) {
            for (auto tag : setup_analyzer.setup_tags(node, tatum::TagType::DATA_ARRIVAL)) {
                fanouts[tag.launch_clock_domain()] += 1;
            }
            for (auto tag : setup_analyzer.setup_tags(node, tatum::TagType::DATA_REQUIRED)) {
                fanouts[tag.launch_clock_domain()] += 1;
            }
        }
    }

    return fanouts;
}

/*
 * Slack and criticality calculation utilities
 */

//Return the criticality of a net's pin in the CLB netlist
float calculate_clb_net_pin_criticality(const SetupTimingInfo& timing_info, const ClusteredPinAtomPinsLookup& pin_lookup, ClusterPinId clb_pin) {

    //There may be multiple atom netlist pins connected to this CLB pin
    float clb_pin_crit = 0.;
    for (const auto atom_pin : pin_lookup.connected_atom_pins(clb_pin)) {
        //Take the maximum of the atom pin criticality as the CLB pin criticality
        clb_pin_crit = std::max(clb_pin_crit, timing_info.setup_pin_criticality(atom_pin));
    }

    return clb_pin_crit;
}

//Returns the worst (maximum) criticality of the set of slack tags specified. Requires the maximum
//required time and worst slack for all domain pairs represent by the slack tags
//
// Criticality (in [0., 1.]) represents how timing-critical something is,
// 0. is non-critical and 1. is most-critical.
//
// This returns 'relaxed per constraint' criticaly as defined in:
//
//     M. Wainberg and V. Betz, "Robust Optimization of Multiple Timing Constraints,"
//         IEEE CAD, vol. 34, no. 12, pp. 1942-1953, Dec. 2015. doi: 10.1109/TCAD.2015.2440316
//
// which handles the trade-off between different timing constraints in multi-clock circuits.
//
// Note that unlike in Wainberg, we calculate the relaxed criticality as a post-processing step.

float calc_relaxed_criticality(const std::map<DomainPair, float>& domains_max_req,
        const std::map<DomainPair, float>& domains_worst_slack,
        const tatum::TimingTags::tag_range tags) {
    //Allowable round-off tolerance during criticality calculation
    constexpr float CRITICALITY_ROUND_OFF_TOLERANCE = 1e-4;


    //Record the maximum criticality over all the tags
    float max_crit = 0.;
    for (const auto& tag : tags) {

        VTR_ASSERT_MSG(tag.type() == tatum::TagType::SLACK, "Tags must be slacks to calculate criticality");

        float slack = tag.time().value();

        auto domain_pair = DomainPair(tag.launch_clock_domain(), tag.capture_clock_domain());

        auto iter = domains_max_req.find(domain_pair);
        VTR_ASSERT_MSG(iter != domains_max_req.end(), "Require the maximum required time for clock domain pair");
        float max_req = iter->second;


        iter = domains_worst_slack.find(domain_pair);
        VTR_ASSERT_MSG(iter != domains_worst_slack.end(), "Require the worst slack for clock domain pair");
        float worst_slack = iter->second;

        if (worst_slack < 0.) {
            //We shift slacks and required time by the most negative slack
            //**in the domain**, to ensure criticality is bounded within [0., 1.]
            //
            //This corresponds to the 'relaxed' criticality from Wainberg et. al.
            float shift = -worst_slack;
            VTR_ASSERT(shift > 0.);

            slack += shift;
            max_req += shift;
        }

        float crit = std::numeric_limits<float>::quiet_NaN();
        if (max_req > 0.) {
            //Standard case
            crit = 1. - (slack / max_req);
            
        } else if (max_req == 0. && slack == 0.) {
            //Special case to avoid divide by zero
            crit = 1.;
        } else {
            std::string msg = vtr::string_fmt("Invalid maximum required time %g (expected >= 0). Shifted slack was %g.", max_req, slack);
            VPR_THROW(VPR_ERROR_TIMING, msg.c_str());
        }


        //Soft check for reasonable criticality values
        VTR_ASSERT_MSG(crit >= 0. - CRITICALITY_ROUND_OFF_TOLERANCE, "Criticality should never be negative");
        VTR_ASSERT_MSG(crit <= 1. + CRITICALITY_ROUND_OFF_TOLERANCE, "Criticality should never be greather than one");

        //Clamp criticality to [0., 1.] to correct round-off
        crit = std::max(0.f, crit);
        crit = std::min(1.f, crit);

        max_crit = std::max(max_crit, crit);
    }
    VTR_ASSERT_MSG(max_crit >= 0., "Criticality should never be negative");
    VTR_ASSERT_MSG(max_crit <= 1., "Criticality should never be greather than one");

    return max_crit;
}

void print_tatum_cpds(std::vector<tatum::TimingPathInfo> cpds) {
    for (auto path : cpds) {
        VTR_LOG("Tatum   %zu -> %zu: least_slack=%g cpd=%g\n", size_t(path.launch_domain()), size_t(path.capture_domain()), float(path.slack()), float(path.delay()));
    }
}
