/* Read in the .route file generated by VPR.
 * This is done in order to perform timing analysis only using the 
 * --analysis option. This file set up the routing tree. It also checks that
 * routing resource nodes and placement is consistent with the
 * .net, .place, or the routing resource graph files. It is assumed
 * that the .route file's formatting matches those as described in the 
 * vtr documentation. For example, the coordinates is assumed to be
 * in (x,y) format. Appropriate error messages are displayed when 
 * formats are incorrect or when the routing file does not match
 * other file's information*/

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <sstream>
#include <string>
#include <unordered_set>
using namespace std;

#include "atom_netlist.h"
#include "atom_netlist_utils.h"
#include "build_rr_graph.h"
#include "vtr_assert.h"
#include "vtr_util.h"
#include "tatum/echo_writer.hpp"
#include "vtr_log.h"
#include "check_route.h"
#include "route_common.h"
#include "vpr_types.h"
#include "globals.h"
#include "vpr_api.h"
#include "read_place.h"
#include "vpr_types.h"
#include "vpr_utils.h"
#include "vpr_error.h"
#include "place_and_route.h"
#include "timing_place.h"
#include "route_export.h"
#include "echo_files.h"
#include "route_common.h"
#include "read_route.h"

/*************Functions local to this module*************/
static void process_route(ifstream &fp, const char* filename, int& lineno);
static void process_nodes(ifstream &fp, ClusterNetId inet, const char* filename, int& lineno);
static void process_nets(ifstream &fp, ClusterNetId inet, string name, std::vector<std::string> input_tokens, const char* filename, int& lineno);
static void process_global_blocks(ifstream &fp, ClusterNetId inet, const char* filename, int& lineno);
static void format_coordinates(int &x, int &y, string coord, ClusterNetId net, const char* filename, const int lineno);
static void format_pin_info(string &pb_name, string & port_name, int & pb_pin_num, string input);
static string format_name(string name);

/*************Global Functions****************************/
void read_route(const char* route_file, const t_router_opts& router_opts, const t_segment_inf* segment_inf, bool verify_file_digests) {

    /* Reads in the routing file to fill in the trace_head and t_clb_opins_used data structure. 
     * Perform a series of verification tests to ensure the netlist, placement, and routing
     * files match */
    auto& device_ctx = g_vpr_ctx.mutable_device();
    auto& place_ctx = g_vpr_ctx.placement();
    /* Begin parsing the file */
    vtr::printf_info("Begin loading packed FPGA routing file.\n");

    string header_str;

    ifstream fp;
    fp.open(route_file);

    int lineno = 0;

    if (!fp.is_open()) {
        vpr_throw(VPR_ERROR_ROUTE, route_file, lineno,
                "Cannot open %s routing file", route_file);
    }

    getline(fp, header_str);
    ++lineno;

    std::vector<std::string> header = vtr::split(header_str);
    if (header[0] == "Placement_File:" && header[2] == "Placement_ID:" && header[3] != place_ctx.placement_id) {
        auto msg = vtr::string_fmt("Placement file %s specified in the routing file"
                                   " does not match the loaded placement (ID %s != %s)", 
                                   header[1].c_str(), header[3].c_str(), place_ctx.placement_id.c_str());
        if (verify_file_digests) {
            vpr_throw(VPR_ERROR_ROUTE, route_file, lineno, msg.c_str());
        } else {
            vtr::printf_warning(route_file, lineno, "%s\n", msg.c_str());
        }
    }

    /*Allocate necessary routing structures*/
    alloc_and_load_rr_node_route_structs();
    init_route_structs(router_opts.bb_factor);

    /*Check dimensions*/
    getline(fp, header_str);
    ++lineno;
    header.clear();
    header = vtr::split(header_str);
    if (header[0] == "Array" && header[1] == "size:" &&
            (vtr::atou(header[2].c_str()) != device_ctx.grid.width() || vtr::atou(header[4].c_str()) != device_ctx.grid.height())) {
        vpr_throw(VPR_ERROR_ROUTE, route_file, lineno,
                "Device dimensions %sx%s specified in the routing file does not match given %dx%d ",
                header[2].c_str(), header[4].c_str(), device_ctx.grid.width(), device_ctx.grid.height());
    }

    /* Read in every net */
    process_route(fp, route_file, lineno);

    fp.close();

    /*Correctly set up the clb opins*/
    recompute_occupancy_from_scratch();

    /* Note: This pres_fac is not necessarily correct since it isn't the first routing iteration*/
    pathfinder_update_cost(router_opts.initial_pres_fac, router_opts.acc_fac);

    reserve_locally_used_opins(router_opts.initial_pres_fac,
            router_opts.acc_fac, true);

    /* Finished loading in the routing, now check it*/
    check_route(router_opts.route_type, device_ctx.num_rr_switches, segment_inf);
    get_serial_num();

    vtr::printf_info("Finished loading route file\n");
}

static void process_route(ifstream &fp, const char* filename, int& lineno) {
    /*Walks through every net and add the routing appropriately*/
    string input;
    std::vector<std::string> tokens;
    while (getline(fp, input)) {
        ++lineno;
        tokens.clear();
        tokens = vtr::split(input);
        if (tokens.empty()) {
            continue; //Skip blank lines
        } else if (tokens[0][0] == '#') {
            continue; //Skip commented lines
        } else if (tokens[0] == "Net") {
            ClusterNetId inet(atoi(tokens[1].c_str()));
            process_nets(fp, inet, tokens[2], tokens, filename, lineno);
        }
    }

    tokens.clear();
}

static void process_nets(ifstream &fp, ClusterNetId inet, string name, std::vector<std::string> input_tokens, const char* filename, int& lineno) {
    /* Check if the net is global or not, and process appropriately */
    auto& cluster_ctx = g_vpr_ctx.mutable_clustering();

    if (input_tokens.size() > 3 && input_tokens[3] == "global"
            && input_tokens[4] == "net" && input_tokens[5] == "connecting:") {
        /* Global net.  Never routed. */
        if (!cluster_ctx.clb_nlist.net_is_global(inet)) {
            vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                    "Net %lu should be a global net", size_t(inet));
        }
        /*erase an extra colon for global nets*/
        name.erase(name.end() - 1);
        name = format_name(name);

        if (0 != cluster_ctx.clb_nlist.net_name(inet).compare(name)) {
            vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                    "Net name %s for net number %lu specified in the routing file does not match given %s",
                    name.c_str(), size_t(inet), cluster_ctx.clb_nlist.net_name(inet).c_str());
        }

        process_global_blocks(fp, inet, filename, lineno);
    } else {
        /* Not a global net */
        if (cluster_ctx.clb_nlist.net_is_global(inet)) {
            vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                    "Net %lu is not a global net", size_t(inet));
        }

        name = format_name(name);

        if (0 != cluster_ctx.clb_nlist.net_name(inet).compare(name)) {
            vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                    "Net name %s for net number %lu specified in the routing file does not match given %s",
                    name.c_str(), size_t(inet), cluster_ctx.clb_nlist.net_name(inet).c_str());
        }

        process_nodes(fp, inet, filename, lineno);
    }
    input_tokens.clear();
    return;
}

static void process_nodes(ifstream & fp, ClusterNetId inet, const char* filename, int& lineno) {
    /* Not a global net. Goes through every node and add it into trace_head*/

    auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
    auto& device_ctx = g_vpr_ctx.mutable_device();
    auto& route_ctx = g_vpr_ctx.mutable_routing();
    auto& place_ctx = g_vpr_ctx.placement();

    t_trace *tptr = route_ctx.trace_head[inet];

    /*remember the position of the last line in order to go back*/
    streampos oldpos = fp.tellg();
    int inode, x, y, x2, y2, ptc, switch_id, offset;
    bool last_node_sink = false;
    int node_count = 0;
    string input;
    std::vector<std::string> tokens;

    /*Walk through every line that begins with Node:*/
    while (getline(fp, input)) {
        ++lineno;

        tokens.clear();
        tokens = vtr::split(input);

        if (tokens.empty()) {
            continue; /*Skip blank lines*/
        } else if (tokens[0][0] == '#') {
            continue; /*Skip commented lines*/
        } else if (tokens[0] == "Net") {
            /*End of the nodes list,
             *  return by moving the position of next char of input stream to be before net*/
            fp.seekg(oldpos);
            if (!last_node_sink) {
                vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                        "Last node in routing has to be a sink type");
            }
            return;
        } else if (input == "\n\nUsed in local cluster only, reserved one CLB pin\n\n") {
            if (cluster_ctx.clb_nlist.net_sinks(inet).size() != 0) {
                vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                        "Net %d should be used in local cluster only, reserved one CLB pin");
            }
            return;
        } else if (tokens[0] == "Node:") {
            /*An actual line, go through each node and add it to the route tree*/
            inode = atoi(tokens[1].c_str());
            auto& node = device_ctx.rr_nodes[inode];

            /*First node needs to be source. It is isolated to correctly set heap head.*/
            if (node_count == 0 && tokens[2] != "SOURCE") {
                vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                        "First node in routing has to be a source type");
            }

            /*Check node types if match rr graph*/
            if (tokens[2] != node.type_string()) {
                vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                        "Node %d has a type that does not match the RR graph", inode);
            }

            /*Keep track of the sink since last node has to be sink type*/
            if (tokens[2] == "SINK") {
                last_node_sink = true;
            } else {
                last_node_sink = false;
            }

            format_coordinates(x, y, tokens[3], inet, filename, lineno);

            if (tokens[4] == "to") {
                format_coordinates(x2, y2, tokens[5], inet, filename, lineno);
                if (node.xlow() != x || node.xhigh() != x2 || node.yhigh() != y2 || node.ylow() != y) {
                    vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                            "The coordinates of node %d does not match the rr graph", inode);
                }
                offset = 2;
            } else {
                if (node.xlow() != x || node.xhigh() != x || node.yhigh() != y || node.ylow() != y) {
                    vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                            "The coordinates of node %d does not match the rr graph", inode);
                }
                offset = 0;
            }

            /* Verify types and ptc*/
            if (tokens[2] == "SOURCE" || tokens[2] == "SINK" || tokens[2] == "OPIN" || tokens[2] == "IPIN") {
                if (tokens[4 + offset] == "Pad:" && device_ctx.grid[x][y].type != device_ctx.IO_TYPE) {
                    vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                            "Node %d is of the wrong type", inode);
                }
            } else if (tokens[2] == "CHANX" || tokens[2] == "CHANY") {
                if (tokens[4 + offset] != "Track:") {
                    vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                            "A %s node have to have track info", tokens[2].c_str());
                }
            }

            ptc = atoi(tokens[5 + offset].c_str());
            if (node.ptc_num() != ptc) {
                vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                        "The ptc num of node %d does not match the rr graph", inode);
            }

            /*Process switches and pb pin info if it is ipin or opin type*/
            if (tokens[6 + offset] != "Switch:") {
                /*This is an opin or ipin, process its pin nums*/
                if (device_ctx.grid[x][y].type != device_ctx.IO_TYPE && (tokens[2] == "IPIN" || tokens[2] == "OPIN")) {
                    int pin_num = device_ctx.rr_nodes[inode].ptc_num();
                    int height_offset = device_ctx.grid[x][y].height_offset;
                    ClusterBlockId iblock = place_ctx.grid_blocks[x][y - height_offset].blocks[0];
                    t_pb_graph_pin *pb_pin = get_pb_graph_node_pin_from_block_pin(iblock, pin_num);
                    t_pb_type *pb_type = pb_pin->parent_node->pb_type;

                    string pb_name, port_name;
                    int pb_pin_num;

                    format_pin_info(pb_name, port_name, pb_pin_num, tokens[6 + offset]);

                    if (pb_name != pb_type->name || port_name != pb_pin->port->name ||
                            pb_pin_num != pb_pin->pin_number) {
                        vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                                "%d node does not have correct pins", inode);
                    }
                } else {
                    vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                            "%d node does not have correct pins", inode);
                }
                switch_id = atoi(tokens[8 + offset].c_str());
            } else {
                switch_id = atoi(tokens[7 + offset].c_str());
            }

            /* Allocate and load correct values to trace_head*/
            if (node_count == 0) {
                route_ctx.trace_head[inet] = alloc_trace_data();
                route_ctx.trace_head[inet]->index = inode;
                route_ctx.trace_head[inet]->iswitch = switch_id;
                route_ctx.trace_head[inet]->next = NULL;
                tptr = route_ctx.trace_head[inet];
                node_count++;
            } else {
                tptr->next = alloc_trace_data();
                tptr = tptr -> next;
                tptr->index = inode;
                tptr->iswitch = switch_id;
                tptr->next = NULL;
                node_count++;
            }
        }
        /*stores last line so can easily go back to read*/
        oldpos = fp.tellg();
    }
}

/*This function goes through all the blocks in a global net and verify it with the
* clustered netlist and the placement */
static void process_global_blocks(ifstream &fp, ClusterNetId inet, const char* filename, int& lineno) {
    auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
    auto& place_ctx = g_vpr_ctx.placement();

    string block, bnum_str;
    int x, y;
    std::vector<std::string> tokens;
    int pin_counter = 0;

    streampos oldpos = fp.tellg();
    /*Walk through every block line*/
    while (getline(fp, block)) {
        ++lineno;
        tokens.clear();
        tokens = vtr::split(block);

        if (tokens.empty()) {
            continue; /*Skip blank lines*/
        } else if (tokens[0][0] == '#') {
            continue; /*Skip commented lines*/
        } else if (tokens[0] != "Block") {
            /*End of blocks, go back to reading nets*/
            fp.seekg(oldpos);
            return;
        } else {
            format_coordinates(x, y, tokens[4], inet, filename, lineno);

            /*remove ()*/
            bnum_str = format_name(tokens[2]);
            /*remove #*/
            bnum_str.erase(bnum_str.begin());
			ClusterBlockId bnum(atoi(bnum_str.c_str()));

            /*Check for name, coordinate, and pins*/
            if (0 != cluster_ctx.clb_nlist.block_name(bnum).compare(tokens[1])) {
                vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                        "Block %s for block number %lu specified in the routing file does not match given %s",
                        tokens[1].c_str(), size_t(bnum), cluster_ctx.clb_nlist.block_name(bnum).c_str());
            }
            if (place_ctx.block_locs[bnum].x != x || place_ctx.block_locs[bnum].y != y) {
                vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                        "The placement coordinates (%d, %d) of %d block does not match given (%d, %d)",
                        x, y, place_ctx.block_locs[bnum].x, place_ctx.block_locs[bnum].y);
            }

			int pin_index = cluster_ctx.clb_nlist.net_pin_physical_index(inet, pin_counter);
            if (cluster_ctx.clb_nlist.block_type(bnum)->pin_class[pin_index] != atoi(tokens[7].c_str())) {
                vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                        "The pin class %d of %lu net does not match given ",
                        atoi(tokens[7].c_str()), size_t(inet), cluster_ctx.clb_nlist.block_type(bnum)->pin_class[pin_index]);
            }
            pin_counter++;
        }
        oldpos = fp.tellg();
    }
}

static void format_coordinates(int &x, int &y, string coord, ClusterNetId net, const char* filename, const int lineno) {
    /*Parse coordinates in the form of (x,y) into correct x and y values*/
    coord = format_name(coord);
    stringstream coord_stream(coord);
    if (!(coord_stream >> x)) {

        vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                "Net %lu has coordinates that is not in the form (x,y)", size_t(net));
    }
    coord_stream.ignore(1, ' ');
    if (!(coord_stream >> y)) {

        vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
                "Net %lu has coordinates that is not in the form (x,y)", size_t(net));
    }
}

static void format_pin_info(string &pb_name, string & port_name, int & pb_pin_num, string input) {
    /*Parse the pin info in the form of pb_name.port_name[pb_pin_num]
     *into its appropriate variables*/
    stringstream pb_info(input);
    getline(pb_info, pb_name, '.');
    getline(pb_info, port_name, '[');
    pb_info >> pb_pin_num;
    if (!pb_info) {
        vpr_throw(VPR_ERROR_ROUTE, __FILE__, __LINE__,
                "Format of this pin info %s is incorrect",
                input.c_str());
    }
}

/*Return actual name by extracting it out of the form of (name)*/
static string format_name(string name) {
    if (name.length() > 2) {
        name.erase(name.begin());
        name.erase(name.end() - 1);
        return name;
    } else {
        vpr_throw(VPR_ERROR_ROUTE, __FILE__, __LINE__,
                "%s should be enclosed by parenthesis",
                name.c_str());
        return NULL;
    }
}
