#include "RoutingGraph.hpp"
#include "Chip.hpp"
#include "Tile.hpp"
#include <regex>
#include <iostream>
#include <algorithm>

namespace Trellis {

// This is ignored for the MachXO2 family- globals are handled during routing
// graph creation.
const Location GlobalLoc(-2, -2);

RoutingGraph::RoutingGraph(const Chip &c) : chip_name(c.info.name), chip_family(c.info.family), max_row(c.get_max_row()), max_col(c.get_max_col())
{
    tiles[GlobalLoc].loc = GlobalLoc;
    for (int y = 0; y <= max_row; y++) {
        for (int x = 0; x <= max_col; x++) {
            Location loc(x, y);
            tiles[loc].loc = loc;
        }
    }
    if (chip_name.find("25F") != string::npos || chip_name.find("12F") != string::npos)
        chip_prefix = "25K_";
    else if (chip_name.find("45F") != string::npos)
        chip_prefix = "45K_";
    else if (chip_name.find("85F") != string::npos)
        chip_prefix = "85K_";
    else if (chip_name.find("1200HC") != string::npos)
        // FIXME: Prefix to distinguish XO, XO2, and XO3?
        chip_prefix = "1200_";
    else
        assert(false);

    if(c.info.family == "MachXO2")
        global_data_machxo2 = get_global_info_machxo2(DeviceLocator{c.info.family, c.info.name});
}

ident_t IdStore::ident(const std::string &str) const
{
    if (str_to_id.find(str) != str_to_id.end()) {
        return str_to_id.at(str);
    } else {
        str_to_id[str] = int(identifiers.size());
        identifiers.push_back(str);
        return str_to_id.at(str);
    }
}

std::string IdStore::to_str(ident_t id) const
{
    return identifiers.at(id);
}

RoutingId IdStore::id_at_loc(int16_t x, int16_t y, const std::string &str) const
{
    RoutingId rid;
    rid.id = ident(str);
    rid.loc = Location(x, y);
    return rid;
}

RoutingId RoutingGraph::globalise_net(int row, int col, const std::string &db_name)
{
    if(chip_family == "ECP5") {
        return globalise_net_ecp5(row, col, db_name);
    } else if(chip_family == "MachXO2") {
        return globalise_net_machxo2(row, col, db_name);
    } else
        throw runtime_error("Unknown chip family: " + chip_family);
}

RoutingId RoutingGraph::globalise_net_ecp5(int row, int col, const std::string &db_name)
{
    static const std::regex e(R"(^([NS]\d+)?([EW]\d+)?_(.*))", std::regex::optimize);
    std::string stripped_name = db_name;
    if (db_name.find("25K_") == 0 || db_name.find("45K_") == 0 || db_name.find("85K_") == 0) {
        if (db_name.substr(0, 4) == chip_prefix) {
            stripped_name = db_name.substr(4);
        } else {
            return RoutingId();
        }
    }
    // Workaround for PCSA/B sharing tile dbs
    if (col >= 69) {
        size_t pcsa_pos = stripped_name.find("PCSA");
        if (pcsa_pos != std::string::npos)
            stripped_name.replace(pcsa_pos + 3, 1, "B");
    }
    if (stripped_name.find("G_") == 0 || stripped_name.find("L_") == 0 || stripped_name.find("R_") == 0) {
        // Global net
        // TODO: quadrants and TAP_DRIVE regions
        // TAP_DRIVE and SPINE wires go in their respective tiles
        // Other globals are placed at a nominal location of (0, 0)
        RoutingId id;
        if (stripped_name.find("G_") == 0 && stripped_name.find("VPTX") == string::npos &&
            stripped_name.find("HPBX") == string::npos && stripped_name.find("HPRX") == string::npos) {
            id.loc.x = 0;
            id.loc.y = 0;
        } else {
            id.loc.x = int16_t(col);
            id.loc.y = int16_t(row);
        }
        id.id = ident(stripped_name);
        return id;
    } else {
        RoutingId id;
        id.loc.x = int16_t(col);
        id.loc.y = int16_t(row);
        // Local net, process prefix
        smatch m;
        if (regex_match(stripped_name, m, e)) {
            for (int i = 1; i < int(m.size()) - 1; i++) {
                string g = m.str(i);
                if (g.empty()) continue;
                if (g[0] == 'N') id.loc.y -= std::stoi(g.substr(1));
                else if (g[0] == 'S') id.loc.y += std::stoi(g.substr(1));
                else if (g[0] == 'W') id.loc.x -= std::stoi(g.substr(1));
                else if (g[0] == 'E') id.loc.x += std::stoi(g.substr(1));
                else
                    assert(false);
            }
            id.id = ident(m.str(m.size() - 1));
        } else {
            id.id = ident(stripped_name);
        }
        if (id.loc.x < 0 || id.loc.x > max_col || id.loc.y < 0 || id.loc.y > max_row)
            return RoutingId(); // TODO: handle edge nets properly
        return id;
    }
}

RoutingId RoutingGraph::globalise_net_machxo2(int row, int col, const std::string &db_name)
{
  static const std::regex e(R"(^([NS]\d+)?([EW]\d+)?_(.*))", std::regex::optimize);
  std::string stripped_name = db_name;

  if (db_name.find("256_") == 0 || db_name.find("640_") == 0) {
      if (db_name.substr(0, 4) == chip_prefix) {
          stripped_name = db_name.substr(4);
      } else {
          return RoutingId();
      }
  }

  if (db_name.find("1200_") == 0 || db_name.find("2000_") == 0 ||
      db_name.find("4000_") == 0 || db_name.find("7000_") == 0) {
      if (db_name.substr(0, 5) == chip_prefix) {
          stripped_name = db_name.substr(5);
      } else {
          return RoutingId();
      }
  }

  if (stripped_name.find("G_") == 0 || stripped_name.find("L_") == 0 || stripped_name.find("R_") == 0 ||
      stripped_name.find("U_") == 0 || stripped_name.find("D_") == 0 || stripped_name.find("BRANCH_") == 0) {
      //size_t sub_idx = 0;

      // if(stripped_name.find("BRANCH_") == 0) {
      //     sub_idx = 7;
      // } else {
      //     sub_idx = 3;
      // }

      return find_machxo2_global_position(row, col, stripped_name);
  } else {
      RoutingId id;
      id.loc.x = int16_t(col);
      id.loc.y = int16_t(row);
      // Local net, process prefix
      smatch m;
      if (regex_match(stripped_name, m, e)) {
          for (int i = 1; i < int(m.size()) - 1; i++) {
              string g = m.str(i);
              if (g.empty()) continue;
              if (g[0] == 'N') id.loc.y -= std::stoi(g.substr(1));
              else if (g[0] == 'S') id.loc.y += std::stoi(g.substr(1));
              else if (g[0] == 'W') {
                  id.loc.x -= std::stoi(g.substr(1));

                  if(id.loc.x < 0) {
                      // Special case: PIO wires on left side have a relative
                      // position placing them outside the chip thanks to MachXO2's
                      // wonderful 1-based column numbering, and lack of dedicated
                      // PIO tiles on the left and right.
                      // Top and bottom unaffected due to dedicated PIO tiles.
                      bool pio_wire = (db_name.find("PADD") != string::npos ||
                          db_name.find("IOLDO") != string::npos ||
                          db_name.find("IOLTO") != string::npos ||
                          db_name.find("JINCK") != string::npos);

                      if((id.loc.x == -1) && pio_wire)
                          id.loc.x = 0;
                  }
              }
              else if (g[0] == 'E') {
                  id.loc.x += std::stoi(g.substr(1));

                  if(id.loc.x > max_col) {
                      bool pio_wire = (db_name.find("PADD") != string::npos ||
                        db_name.find("IOLDO") != string::npos ||
                        db_name.find("IOLTO") != string::npos||
                        db_name.find("JINCK") != string::npos);

                      // Same deal as left side, except the position exceeds
                      // the maximum row.
                      // TODO: Should this become part of general edge-handling
                      // code, rather than a special case in the generic relative-
                      // position logic?
                      if((id.loc.x == max_col + 1) && pio_wire)
                          id.loc.x = max_col;
                  }
              }
              else
                  assert(false);
          }
          id.id = ident(m.str(m.size() - 1));
      } else {
          id.id = ident(stripped_name);
      }
      if (id.loc.x < 0 || id.loc.x > max_col || id.loc.y < 0 || id.loc.y > max_row)
          return RoutingId(); // TODO: handle edge nets properly
      return id;
  }
}

void RoutingGraph::add_arc(Location loc, const RoutingArc &arc)
{
    RoutingId arcId;
    arcId.loc = loc;
    arcId.id = arc.id;
    add_wire(arc.source);
    add_wire(arc.sink);
    tiles[loc].arcs[arc.id] = arc;
    tiles[arc.sink.loc].wires.at(arc.sink.id).uphill.push_back(arcId);
    tiles[arc.source.loc].wires.at(arc.source.id).downhill.push_back(arcId);
}

void RoutingGraph::add_wire(RoutingId wire)
{
    RoutingTileLoc &tile = tiles[wire.loc];
    if (tile.wires.find(wire.id) == tile.wires.end()) {
        RoutingWire rw;
        rw.id = wire.id;
        tiles[wire.loc].wires[rw.id] = rw;
    }
}

void RoutingGraph::add_bel(RoutingBel &bel)
{
    tiles[bel.loc].bels[bel.name] = bel;
}

void RoutingGraph::add_bel_input(RoutingBel &bel, ident_t pin, int wire_x, int wire_y, ident_t wire_name) {
    RoutingId wireId, belId;
    wireId.id = wire_name;
    wireId.loc.x = wire_x;
    wireId.loc.y = wire_y;
    belId.id = bel.name;
    belId.loc = bel.loc;
    add_wire(wireId);
    bel.pins[pin] = make_pair(wireId, PORT_IN);
    tiles[wireId.loc].wires[wireId.id].belsDownhill.push_back(make_pair(belId, pin));
}

void RoutingGraph::add_bel_output(RoutingBel &bel, ident_t pin, int wire_x, int wire_y, ident_t wire_name) {
    RoutingId wireId, belId;
    wireId.id = wire_name;
    wireId.loc.x = wire_x;
    wireId.loc.y = wire_y;
    belId.id = bel.name;
    belId.loc = bel.loc;
    add_wire(wireId);
    bel.pins[pin] = make_pair(wireId, PORT_OUT);
    tiles[wireId.loc].wires[wireId.id].belsUphill.push_back(make_pair(belId, pin));
}

RoutingId RoutingGraph::find_machxo2_global_position(int row, int col, const std::string &db_name) {
    // Globals are given their nominal position, even if they span multiple
    // tiles, by the following rules (determined by a combination of regexes
    // on db_name and row/col):
    smatch m;
    pair<int, int> center = center_map[make_pair(max_row, max_col)];
    RoutingId curr_global;

    GlobalType strategy = get_global_type_from_name(db_name, m);

    // All globals in the center tile get a nominal position of the center
    // tile. We have to use regexes because a number of these connections
    // in the center mux have config bits spread across multiple tiles
    // (although few nets actually have routing bits which cross tiles).
    //
    // This handles L/R_HPSX as well. DCCs are handled a bit differently
    // until we can determine they only truly exist in center tile (the row,
    // col, and db_name will still be enough to distinguish them).
    if(strategy == GlobalType::CENTER) {
        // XXX: This is a MachXO2-1200HC-specific hack; VPRXCLKI0's routing
        // config bits are split across multiple tiles. Arcs do not store data
        // about their tile position in the routing graph (as that's the DB's
        // responsibility). Even so, we do _not_ want the same physical arc
        // that appears in two tiles in the DB appearing twice in the routing
        // graph. So for now, special-case and remove the second arc at
        // (12, 9).
        //
        // If more than one arc has this problem, we may need to change this
        // function signature to be device-specific, and find a better way to
        // store this info along with the routing graph besides special-casing.
        if((db_name.find("G_VPRXCLKI0") != string::npos) && row == 9 && col == 12)
            return RoutingId();

        curr_global.id = ident(db_name);
        curr_global.loc.x = center.second;
        curr_global.loc.y = center.first;
        return curr_global;

    // If we found a global emanating from the CENTER MUX, return a L_/R_
    // global net in the center tile based upon the current tile position
    // (specifically column).
    } else if(strategy == GlobalType::LEFT_RIGHT) {
        assert(row == center.first);
        // Prefixes only required in the center tile.
        assert(db_name[0] == 'G');

        std::string db_copy = db_name;

        // Center column tiles connect to the left side of the center mux.
        if(col <= center.second)
            db_copy[0] = 'L';
        else
            db_copy[0] = 'R';

        curr_global.id = ident(db_copy);
        curr_global.loc.x = center.second;
        curr_global.loc.y = center.first;
        return curr_global;

    // U/D wires get the nominal position of center row, current column.
    // Both U_/D_ and G_ prefixes are handled here.
    } else if(strategy == GlobalType::UP_DOWN) {
        std::string db_copy = db_name;
        std::vector<int> & ud_conns_in_col = global_data_machxo2.ud_conns[col];
        auto conn_begin = ud_conns_in_col.begin();
        auto conn_end = ud_conns_in_col.end();
        int conn_no = std::stoi(m.str(1));

        // First check whether the requested global is in the current column.
        // If not, no point in continuing.
        if(std::find(conn_begin, conn_end, conn_no) == conn_end)
            return RoutingId();

        // Special case the center row, which will have both U/D wires.
        if(row == center.first) {
            assert((db_name[0] == 'U') || (db_name[0] == 'D'));
        } else {
            // Otherwise choose an U_/D_ wire at nominal position based on
            // the current tile's row.
            // Prefixes only required in the center row.
            assert(db_name[0] == 'G');

            // Center column tiles are considered above the center mux,
            // despite sharing the same tile.
            if(row <= center.first)
                db_copy[0] = 'U';
            else
                db_copy[0] = 'D';
        }

        curr_global.id = ident(db_copy);
        curr_global.loc.x = col;
        curr_global.loc.y = center.first;
        return curr_global;

    // BRANCH wires get nominal position of the row/col where they connect
    // to U_/D_ routing. We need the global_data_machxo2 struct to figure
    // out this information.
    } else if(strategy == GlobalType::BRANCH) {
        std::vector<int> candidate_cols;

        if(col > 1)
            candidate_cols.push_back(col - 2);
        if(col > 0)
            candidate_cols.push_back(col - 1);
        candidate_cols.push_back(col);
        if(col < max_col)
            candidate_cols.push_back(col + 1);

        for(auto curr_col : candidate_cols) {
            std::vector<int> & ud_conns_in_col = global_data_machxo2.ud_conns[curr_col];
            auto conn_begin = ud_conns_in_col.begin();
            auto conn_end = ud_conns_in_col.end();
            int conn_no = std::stoi(m.str(1));

            // First check whether the requested global is in the current column.
            // If not, no point in continuing.
            if(std::find(conn_begin, conn_end, conn_no) != conn_end) {
                curr_global.id = ident(db_name);
                curr_global.loc.x = curr_col;
                curr_global.loc.y = row;
                break;
            }
        }

        // One of the candidate columns should have had the correct U/D
        // connection to route to.
        assert(curr_global != RoutingId());
        return curr_global;

    // For OSCH, and DCCs assign nominal position of current requested tile.
    // DCM only exist in center tile but have their routing spread out
    // across tiles.
    } else if(strategy == GlobalType::OTHER) {
        curr_global.id = ident(db_name);
        curr_global.loc.x = col;
        curr_global.loc.y = row;
        return curr_global;
    } else {
        // TODO: Not fuzzed and/or handled yet!
        return RoutingId();
    }
}

RoutingGraph::GlobalType RoutingGraph::get_global_type_from_name(const std::string &db_name, smatch &match) {
    // A RoutingId uniquely describes a net on the chip- using a string
    // identifier (id- converted to int), and a nominal position (loc).
    // Two RoutingIds with the same id and loc represent the same net, so
    // we can use heuristics to connect globals to the rest of the routing
    // graph properly, given the current tile position and the global's
    // identifier.

    // First copy regexes from utils.nets.machxo2, adjusting as necessary for
    // prefixes and regex syntax. Commented-out ones are not ready yet:
    // Globals
    static const std::regex global_entry(R"(G_VPRX(\d){2}00)", std::regex::optimize);
    static const std::regex global_left_right(R"([LR]_HPSX(\d){2}00)", std::regex::optimize);
    static const std::regex global_left_right_g(R"(G_HPSX(\d){2}00)", std::regex::optimize);
    static const std::regex global_up_down(R"([UD]_VPTX(\d){2}00)", std::regex::optimize);
    static const std::regex global_up_down_g(R"(G_VPTX(\d){2}00)", std::regex::optimize);
    static const std::regex global_branch(R"(BRANCH_HPBX(\d){2}00)", std::regex::optimize);

    // High Fanout Secondary Nets
    // static const std::regex hfsn_entry(R"(G_VSRX(\d){2}00)", std::regex::optimize);
    // static const std::regex hfsn_left_right(R"(G_HSSX(\d){2}00)", std::regex::optimize);
    // L2Rs control bidirectional portion of HFSNs!!
    // static const std::regex hfsn_l2r(R"(G_HSSX(\d){2}00_[RL]2[LR])", std::regex::optimize);
    // static const std::regex hfsn_up_down(R"(G_VSTX(\d){2}00)", std::regex::optimize);
    // HSBX(\d){2}00 are fixed connections to HSBX(\d){2}01s.
    // static const std::regex hfsn_branch(R"(G_HSBX(\d){2}0[01])", std::regex::optimize);

    // Center Mux
    // Outputs- entry to DCCs connected to globals (VPRXI -> DCC -> VPRX) *
    static const std::regex center_mux_glb_out(R"(G_VPRXCLKI\d+)", std::regex::optimize);
    // Outputs- connected to ECLKBRIDGEs *
    // static const std::regex center_mux_ebrg_out(R"(G_EBRG(\d){1}CLK(\d){1})", std::regex::optimize);

    // Inputs- CIB routing to HFSNs
    // static const std::regex cib_out_to_hfsn(R"(G_JSNETCIB([TBRL]|MID)(\d){1})", std::regex::optimize);
    // Inputs- CIB routing to globals
    static const std::regex cib_out_to_glb(R"(G_J?PCLKCIB(L[TBRL]Q|MID|VIQ[TBRL])(\d){1})", std::regex::optimize);
    // Inputs- CIB routing to ECLKBRIDGEs
    // static const std::regex cib_out_to_eclk(R"(G_J?ECLKCIB[TBRL](\d){1})", std::regex::optimize);

    // Inputs- Edge clocks dividers
    // static const std::regex eclk_out(R"(G_J?[TBRL]CDIV(X(\d){1}|(\d){2}))", std::regex::optimize);
    // Inputs- PLL
    // static const std::regex pll_out(R"(G_J?[LR]PLLCLK\d+)", std::regex::optimize);
    // Inputs- Clock pads
    // static const std::regex clock_pin(R"(G_J?PCLK[TBLR]\d+)", std::regex::optimize);

    // Part of center-mux but can also be found elsewhere
    // DCCs connected to globals *
    static const std::regex dcc_sig(R"(G_J?(CLK[IO]|CE)(\d){1}[TB]?_DCC)", std::regex::optimize);

    // DCMs- connected to DCCs on globals 6 and 7 *
    static const std::regex dcm_sig(R"(G_J?(CLK(\d){1}_|SEL|DCMOUT)(\d){1}_DCM)", std::regex::optimize);

    // ECLKBRIDGEs- TODO
    // static const std::regex eclkbridge_sig(R"(G_J?(CLK(\d){1}_|SEL|ECSOUT)(\d){1}_ECLKBRIDGECS)", std::regex::optimize);

    // Oscillator output
    static const std::regex osc_clk(R"(G_J?OSC_.*)", std::regex::optimize);

    // Soft Error Detection Clock *
    // static const std::regex sed_clk(R"(G_J?SEDCLKOUT)", std::regex::optimize);

    // PLL/DLL Clocks
    // static const std::regex pll_clk(R"(G_[TB]ECLK\d)", std::regex::optimize);

    // PG/INRD/LVDS
    // static const std::regex pg(R"(G_PG)", std::regex::optimize);
    // static const std::regex inrd(R"(G_INRD)", std::regex::optimize);
    // static const std::regex vds(R"(G_LVDS)", std::regex::optimize);

    // DDR
    // static const std::regex ddrclkpol(R"(G_DDRCLKPOL)", std::regex::optimize);
    // static const std::regex dqsr90(R"(G_DQSR90)", std::regex::optimize);
    // static const std::regex qsw90(R"(G_DQSW90)", std::regex::optimize);

    if(regex_match(db_name, match, global_entry) ||
        regex_match(db_name, match, global_left_right) ||
        regex_match(db_name, match, center_mux_glb_out) ||
        regex_match(db_name, match, cib_out_to_glb) ||
        regex_match(db_name, match, dcm_sig)) {
        return GlobalType::CENTER;
    } else if(regex_match(db_name, match, global_left_right_g)) {
        return GlobalType::LEFT_RIGHT;
    } else if(regex_match(db_name, match, global_up_down) ||
        regex_match(db_name, match, global_up_down_g)) {
        return GlobalType::UP_DOWN;
    } else if(regex_match(db_name, match, global_branch)) {
        return GlobalType::BRANCH;
    } else if(regex_match(db_name, match, dcc_sig) ||
        regex_match(db_name, match, osc_clk)) {
        return GlobalType::OTHER;
    } else {
        // TODO: Not fuzzed and/or handled yet!
        return GlobalType::NONE;
    }
}

}
