// Tool to test routing from one node to another node.
//
// This tool is intended to allow extremely verbose router output on exactly
// one path to diagnose router behavior, e.g. look ahead and A* characteristics.
//
// Usage follows typically VPR invocation, except that no circuit is actually
// used.
//
// Tool can either perform one route between a source (--source_rr_node) and
// a sink (--sink_rr_node), or profile a source to all tiles (set
// --source_rr_node and "--profile_source true").
#include <cstdio>
#include <cstring>
#include <ctime>
#include <fstream>

#include "vtr_error.h"
#include "vtr_memory.h"
#include "vtr_log.h"
#include "vtr_time.h"

#include "tatum/error.hpp"

#include "vpr_error.h"
#include "vpr_api.h"
#include "vpr_signal_handler.h"

#include "globals.h"

#include "net_delay.h"
#include "RoutingDelayCalculator.h"
#include "place_and_route.h"
#include "router_delay_profiling.h"
#include "route_tree_type.h"
#include "route_common.h"
#include "route_timing.h"
#include "route_tree_timing.h"
#include "route_export.h"
#include "rr_graph.h"
#include "rr_graph2.h"
#include "timing_place_lookup.h"

struct t_route_util_options {
    /* Router diag tool Options */
    argparse::ArgValue<int> source_rr_node;
    argparse::ArgValue<int> sink_rr_node;
    argparse::ArgValue<bool> profile_source;

    t_options options;
};

t_route_util_options read_route_util_options(int argc, const char** argv);

/*
 * Exit codes to signal success/failure to scripts
 * calling vpr
 */
constexpr int SUCCESS_EXIT_CODE = 0; //Everything OK
constexpr int ERROR_EXIT_CODE = 1; //Something went wrong internally
constexpr int INTERRUPTED_EXIT_CODE = 3; //VPR was interrupted by the user (e.g. SIGINT/ctr-C)

static void do_one_route(int source_node, int sink_node,
        const t_router_opts& router_opts,
        const std::vector<t_segment_inf>& segment_inf) {
    /* Returns true as long as found some way to hook up this net, even if that *
     * way resulted in overuse of resources (congestion).  If there is no way   *
     * to route this net, even ignoring congestion, it returns false.  In this  *
     * case the rr_graph is disconnected and you can give up.                   */
    auto& device_ctx = g_vpr_ctx.device();
    auto& route_ctx = g_vpr_ctx.routing();

    t_rt_node* rt_root = init_route_tree_to_source_no_net(source_node);
    enable_router_debug(router_opts, ClusterNetId(), sink_node);

    /* Update base costs according to fanout and criticality rules */
    update_rr_base_costs(1);

    //maximum bounding box for placement
    t_bb bounding_box;
    bounding_box.xmin = 0;
    bounding_box.xmax = device_ctx.grid.width() + 1;
    bounding_box.ymin = 0;
    bounding_box.ymax = device_ctx.grid.height() + 1;

    t_conn_cost_params cost_params;
    cost_params.criticality = 1.;
    cost_params.astar_fac = router_opts.astar_fac;
    cost_params.bend_cost = router_opts.bend_cost;

    route_budgets budgeting_inf;

    init_heap(device_ctx.grid);

    std::vector<int> modified_rr_node_inf;
    RouterStats router_stats;
    auto router_lookahead = make_router_lookahead(
            router_opts.lookahead_type,
            router_opts.write_router_lookahead,
            router_opts.read_router_lookahead,
            segment_inf
            );
    t_heap* cheapest = timing_driven_route_connection_from_route_tree(rt_root, sink_node, cost_params, bounding_box, *router_lookahead, modified_rr_node_inf, router_stats);

    bool found_path = (cheapest != nullptr);
    if (found_path) {
        VTR_ASSERT(cheapest->index == sink_node);

        t_rt_node* rt_node_of_sink = update_route_tree(cheapest, nullptr);
        free_heap_data(cheapest);

        //find delay
        float net_delay = rt_node_of_sink->Tdel;
        VTR_LOG("Routed successfully, delay = %g!\n", net_delay);
        VTR_LOG("\n");
        print_route_tree_node(rt_root);
        VTR_LOG("\n");
        print_route_tree(rt_root);
        VTR_LOG("\n");

        VTR_ASSERT_MSG(route_ctx.rr_node_route_inf[rt_root->inode].occ() <= device_ctx.rr_nodes[rt_root->inode].capacity(), "SOURCE should never be congested");
        free_route_tree(rt_root);
    } else {
        VTR_LOG("Routed failed");
    }

    //Reset for the next router call
    empty_heap();
    reset_path_costs(modified_rr_node_inf);
}

static void profile_source(int source_rr_node,
        const t_router_opts& router_opts,
        const std::vector<t_segment_inf>& segment_inf) {
    vtr::ScopedStartFinishTimer timer("Profiling source");
    const auto& device_ctx = g_vpr_ctx.device();
    const auto& grid = device_ctx.grid;

    auto router_lookahead = make_router_lookahead(
            router_opts.lookahead_type,
            router_opts.write_router_lookahead,
            router_opts.read_router_lookahead,
            segment_inf
            );
    RouterDelayProfiler profiler(router_lookahead.get());

    int start_x = 0;
    int end_x = grid.width() - 1;
    int start_y = 0;
    int end_y = grid.height() - 1;

    vtr::Matrix<float> delays({grid.width(), grid.height()},
            std::numeric_limits<float>::infinity());
    vtr::Matrix<int> sink_nodes({grid.width(), grid.height()}, OPEN);

    for (int sink_x = start_x; sink_x <= end_x; sink_x++) {
        for (int sink_y = start_y; sink_y <= end_y; sink_y++) {
            if(device_ctx.grid[sink_x][sink_y].type == device_ctx.EMPTY_TYPE) {
                continue;
            }

            auto best_sink_ptcs = get_best_classes(RECEIVER,
                    device_ctx.grid[sink_x][sink_y].type);
            bool successfully_routed;
            for (int sink_ptc : best_sink_ptcs) {
                VTR_ASSERT(sink_ptc != OPEN);

                int sink_rr_node = get_rr_node_index(device_ctx.rr_node_indices, sink_x, sink_y, SINK, sink_ptc);

                if (directconnect_exists(source_rr_node, sink_rr_node)) {
                    //Skip if we shouldn't measure direct connects and a direct connect exists
                    continue;
                }

                VTR_ASSERT(sink_rr_node != OPEN);

                {
                    vtr::ScopedStartFinishTimer delay_timer(vtr::string_fmt(
                        "Routing Src: %d Sink: %d", source_rr_node,
                        sink_rr_node));
                    successfully_routed = profiler.calculate_delay(source_rr_node, sink_rr_node,
                                                        router_opts,
                                                        &delays[sink_x][sink_y]);
                }

                if (successfully_routed) {
                    sink_nodes[sink_x][sink_y] = sink_rr_node;
                    break;
                }
            }
        }
    }

    VTR_LOG("Delay matrix from source_rr_node: %d\n", source_rr_node);
    for(size_t iy = 0; iy < delays.dim_size(1); ++iy) {
        for(size_t ix = 0; ix < delays.dim_size(0); ++ix) {
            VTR_LOG("%g,", delays[ix][iy]);
        }
        VTR_LOG("\n");
    }
    VTR_LOG("\n");

    VTR_LOG("Sink matrix used for delay matrix:\n");
    for(size_t iy = 0; iy < sink_nodes.dim_size(1); ++iy) {
        for(size_t ix = 0; ix < sink_nodes.dim_size(0); ++ix) {
            VTR_LOG("%d,", sink_nodes[ix][iy]);
        }
        VTR_LOG("\n");
    }
    VTR_LOG("\n");
}


static t_chan_width setup_chan_width(t_router_opts router_opts,
        t_chan_width_dist chan_width_dist) {
    /*we give plenty of tracks, this increases routability for the */
    /*lookup table generation */

    int width_fac;

    if (router_opts.fixed_channel_width == NO_FIXED_CHANNEL_WIDTH) {
        auto& device_ctx = g_vpr_ctx.device();

        auto type = physical_tile_type(find_most_common_block_type(device_ctx.grid));

        width_fac = 4 * type->num_pins;
        /*this is 2x the value that binary search starts */
        /*this should be enough to allow most pins to   */
        /*connect to tracks in the architecture */
    } else {
        width_fac = router_opts.fixed_channel_width;
    }

    return init_chan(width_fac, chan_width_dist);
}

t_route_util_options read_route_util_options(int argc, const char** argv) {
    //Explicitly initialize for zero initialization
    t_route_util_options args = t_route_util_options();
    auto parser = create_arg_parser(argv[0], args.options);

    auto& route_diag_grp = parser.add_argument_group("route diagnostic options");
    route_diag_grp.add_argument(args.sink_rr_node, "--sink_rr_node")
        .help("Sink RR node to route for route_diag.")
        .show_in(argparse::ShowIn::HELP_ONLY);
    route_diag_grp.add_argument(args.source_rr_node, "--source_rr_node")
        .help("Source RR node to route for route_diag.")
        .show_in(argparse::ShowIn::HELP_ONLY);
    route_diag_grp.add_argument(args.profile_source, "--profile_source")
        .help(
            "Profile routes from source to IPINs at all locations."
            "This is similiar to the placer delay matrix construction.")
        .show_in(argparse::ShowIn::HELP_ONLY);

    parser.parse_args(argc, argv);

    set_conditional_defaults(args.options);

    verify_args(args.options);

    return args;
}

int main(int argc, const char **argv) {
    t_options Options = t_options();
    t_arch Arch = t_arch();
    t_vpr_setup vpr_setup = t_vpr_setup();

    try {
        vpr_install_signal_handler();

        vpr_initialize_logging();

        /* Print title message */
        vpr_print_title();

        t_route_util_options route_options = read_route_util_options(argc, argv);
        Options = route_options.options;

        /* Read architecture, and circuit netlist */
        vpr_init_with_options(&Options, &vpr_setup, &Arch);

        vpr_create_device_grid(vpr_setup, Arch);

        vpr_setup_clock_networks(vpr_setup, Arch);


        t_chan_width chan_width = setup_chan_width(
                vpr_setup.RouterOpts,
                Arch.Chans);
        alloc_routing_structs(
                chan_width,
                vpr_setup.RouterOpts,
                &vpr_setup.RoutingArch,
                vpr_setup.Segments,
                Arch.Directs,
                Arch.num_directs
                );

        if(route_options.profile_source) {
            profile_source(
                route_options.source_rr_node,
                vpr_setup.RouterOpts,
                vpr_setup.Segments
                );
        } else {
            do_one_route(
                    route_options.source_rr_node, 
                    route_options.sink_rr_node,
                    vpr_setup.RouterOpts,
                    vpr_setup.Segments);
        }
        free_routing_structs();

        /* free data structures */
        vpr_free_all(Arch, vpr_setup);

    } catch (const tatum::Error& tatum_error) {
        vtr::printf_error(__FILE__, __LINE__, "STA Engine: %s\n", tatum_error.what());

        return ERROR_EXIT_CODE;

    } catch (const VprError& vpr_error) {
        vpr_print_error(vpr_error);

        if (vpr_error.type() == VPR_ERROR_INTERRUPTED) {
            return INTERRUPTED_EXIT_CODE;
        } else {
            return ERROR_EXIT_CODE;
        }

    } catch (const vtr::VtrError& vtr_error) {
        vtr::printf_error(__FILE__, __LINE__, "%s:%d %s\n", vtr_error.filename_c_str(), vtr_error.line(), vtr_error.what());

        return ERROR_EXIT_CODE;
    }

    /* Signal success to scripts */
    return SUCCESS_EXIT_CODE;
}
