#include "Chip.hpp"
#include "Tile.hpp"
#include "Database.hpp"
#include "Util.hpp"
#include "RoutingGraph.hpp"
#include "BitDatabase.hpp"
#include "Bels.hpp"
#include <algorithm>
#include <iostream>
using namespace std;

namespace Trellis {

Chip::Chip(string name) : Chip(get_chip_info(find_device_by_name(name)))
{}

Chip::Chip(uint32_t idcode) : Chip(get_chip_info(find_device_by_idcode(idcode)))
{}

Chip::Chip(const Trellis::ChipInfo &info) : info(info), cram(info.num_frames, info.bits_per_frame)
{
    vector<TileInfo> allTiles = get_device_tilegrid(DeviceLocator{info.family, info.name});
    for (const auto &tile : allTiles) {
        tiles[tile.name] = make_shared<Tile>(tile, *this);
        int row, col;
        tie(row, col) = tile.get_row_col();
        if (int(tiles_at_location.size()) <= row) {
            tiles_at_location.resize(row+1);
        }
        if (int(tiles_at_location.at(row).size()) <= col) {
            tiles_at_location.at(row).resize(col+1);
        }
        tiles_at_location.at(row).at(col).push_back(make_pair(tile.name, tile.type));
    }

    if(info.family == "ECP5")
        global_data_ecp5 = get_global_info_ecp5(DeviceLocator{info.family, info.name});
    else if(info.family == "MachXO2")
        global_data_machxo2 = get_global_info_machxo2(DeviceLocator{info.family, info.name});
    else
        throw runtime_error("Unknown chip family " + info.family);
}

shared_ptr<Tile> Chip::get_tile_by_name(string name)
{
    return tiles.at(name);
}

vector<shared_ptr<Tile>> Chip::get_tiles_by_position(int row, int col)
{
    vector<shared_ptr<Tile>> result;
    for (const auto &tile : tiles) {
        if (tile.second->info.get_row_col() == make_pair(row, col))
            result.push_back(tile.second);
    }
    return result;
}

string Chip::get_tile_by_position_and_type(int row, int col, string type) {
    for (const auto &tile : tiles_at_location.at(row).at(col)) {
        if (tile.second == type)
            return tile.first;
    }
    throw runtime_error(fmt("no suitable tile found at R" << row << "C" << col));
}

string Chip::get_tile_by_position_and_type(int row, int col, set<string> type) {
    for (const auto &tile : tiles_at_location.at(row).at(col)) {
        if (type.find(tile.second) != type.end())
            return tile.first;
    }
    throw runtime_error(fmt("no suitable tile found at R" << row << "C" << col));
}


vector<shared_ptr<Tile>> Chip::get_tiles_by_type(string type)
{
    vector<shared_ptr<Tile>> result;
    for (const auto &tile : tiles) {
        if (tile.second->info.type == type)
            result.push_back(tile.second);
    }
    return result;
}

vector<shared_ptr<Tile>> Chip::get_all_tiles()
{
    vector<shared_ptr<Tile>> result;
    for (const auto &tile : tiles) {
        result.push_back(tile.second);
    }
    return result;
}

int Chip::get_max_row() const
{
    return info.max_row;
}

int Chip::get_max_col() const
{
    return info.max_col;
}

ChipDelta operator-(const Chip &a, const Chip &b)
{
    ChipDelta delta;
    for (const auto &tile : a.tiles) {
        CRAMDelta cd = tile.second->cram - b.tiles.at(tile.first)->cram;
        if (!cd.empty())
            delta[tile.first] = cd;
    }
    return delta;
}

shared_ptr<RoutingGraph> Chip::get_routing_graph()
{
    if(info.family == "ECP5") {
        return get_routing_graph_ecp5();
    } else if(info.family == "MachXO2") {
        return get_routing_graph_machxo2();
    } else
      throw runtime_error("Unknown chip family: " + info.family);
}

shared_ptr<RoutingGraph> Chip::get_routing_graph_ecp5()
{
    shared_ptr<RoutingGraph> rg(new RoutingGraph(*this));
    //cout << "Building routing graph" << endl;
    for (auto tile_entry : tiles) {
        shared_ptr<Tile> tile = tile_entry.second;
        //cout << "    Tile " << tile->info.name << endl;
        shared_ptr<TileBitDatabase> bitdb = get_tile_bitdata(TileLocator{info.family, info.name, tile->info.type});
        bitdb->add_routing(tile->info, *rg);
        int x, y;
        tie(y, x) = tile->info.get_row_col();
        // SLICE Ecp5Bels
        if (tile->info.type == "PLC2") {
            for (int z = 0; z < 4; z++)
                Ecp5Bels::add_lc(*rg, x, y, z);
        }
        // PIO Ecp5Bels
        if (tile->info.type.find("PICL0") != string::npos || tile->info.type.find("PICR0") != string::npos)
            for (int z = 0; z < 4; z++) {
                Ecp5Bels::add_pio(*rg, x, y, z);
                Ecp5Bels::add_iologic(*rg, x, y, z, false);
            }
        if (tile->info.type.find("PIOT0") != string::npos || (tile->info.type.find("PICB0") != string::npos && tile->info.type != "SPICB0"))
            for (int z = 0; z < 2; z++) {
                Ecp5Bels::add_pio(*rg, x, y, z);
                Ecp5Bels::add_iologic(*rg, x, y, z, true);
            }
        if (tile->info.type == "SPICB0") {
            Ecp5Bels::add_pio(*rg, x, y, 0);
            Ecp5Bels::add_iologic(*rg, x, y, 0, true);
        }
        // DCC Ecp5Bels
        if (tile->info.type == "LMID_0")
            for (int z = 0; z < 14; z++)
                Ecp5Bels::add_dcc(*rg, x, y, "L", std::to_string(z));
        if (tile->info.type == "RMID_0")
            for (int z = 0; z < 14; z++)
                Ecp5Bels::add_dcc(*rg, x, y, "R", std::to_string(z));
        if (tile->info.type == "TMID_0")
            for (int z = 0; z < 12; z++)
                Ecp5Bels::add_dcc(*rg, x, y, "T", std::to_string(z));
        if (tile->info.type == "BMID_0V" || tile->info.type == "BMID_0H")
            for (int z = 0; z < 16; z++)
                Ecp5Bels::add_dcc(*rg, x, y, "B", std::to_string(z));
        // RAM Ecp5Bels
        if (tile->info.type == "MIB_EBR0" || tile->info.type == "EBR_CMUX_UR" || tile->info.type == "EBR_CMUX_LR"
            || tile->info.type == "EBR_CMUX_LR_25K")
            Ecp5Bels::add_bram(*rg, x, y, 0);
        if (tile->info.type == "MIB_EBR2")
            Ecp5Bels::add_bram(*rg, x, y, 1);
        if (tile->info.type == "MIB_EBR4")
            Ecp5Bels::add_bram(*rg, x, y, 2);
        if (tile->info.type == "MIB_EBR6")
            Ecp5Bels::add_bram(*rg, x, y, 3);
        // DSP Ecp5Bels
        if (tile->info.type == "MIB_DSP0")
            Ecp5Bels::add_mult18(*rg, x, y, 0);
        if (tile->info.type == "MIB_DSP1")
            Ecp5Bels::add_mult18(*rg, x, y, 1);
        if (tile->info.type == "MIB_DSP4")
            Ecp5Bels::add_mult18(*rg, x, y, 4);
        if (tile->info.type == "MIB_DSP5")
            Ecp5Bels::add_mult18(*rg, x, y, 5);
        if (tile->info.type == "MIB_DSP3")
            Ecp5Bels::add_alu54b(*rg, x, y, 3);
        if (tile->info.type == "MIB_DSP7")
            Ecp5Bels::add_alu54b(*rg, x, y, 7);
        // PLL Ecp5Bels
        if (tile->info.type == "PLL0_UL")
            Ecp5Bels::add_pll(*rg, "UL", x+1, y);
        if (tile->info.type == "PLL0_LL")
            Ecp5Bels::add_pll(*rg, "LL", x, y-1);
        if (tile->info.type == "PLL0_LR")
            Ecp5Bels::add_pll(*rg, "LR", x, y-1);
        if (tile->info.type == "PLL0_UR")
            Ecp5Bels::add_pll(*rg, "UR", x-1, y);
        // DCU and ancillary Ecp5Bels
        if (tile->info.type == "DCU0") {
            Ecp5Bels::add_dcu(*rg, x, y);
            Ecp5Bels::add_extref(*rg, x, y);
        }
        if (tile->info.type == "BMID_0H")
            for (int z = 0; z < 2; z++)
                Ecp5Bels::add_pcsclkdiv(*rg, x, y-1, z);
        // Config/system Ecp5Bels
        if (tile->info.type == "EFB0_PICB0") {
            Ecp5Bels::add_misc(*rg, "GSR", x, y-1);
            Ecp5Bels::add_misc(*rg, "JTAGG", x, y-1);
            Ecp5Bels::add_misc(*rg, "OSCG", x, y-1);
            Ecp5Bels::add_misc(*rg, "SEDGA", x, y-1);
        }
        if (tile->info.type == "DTR")
            Ecp5Bels::add_misc(*rg, "DTR", x, y-1);
        if (tile->info.type == "EFB1_PICB1")
            Ecp5Bels::add_misc(*rg, "USRMCLK", x-5, y);
        if (tile->info.type == "ECLK_L") {
            Ecp5Bels::add_ioclk_bel(*rg, "CLKDIVF", x-2, y, 0, 7);
            Ecp5Bels::add_ioclk_bel(*rg, "CLKDIVF", x-2, y, 1, 6);
            Ecp5Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x-2, y, 0, 7);
            Ecp5Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x-2, y, 1, 7);
            Ecp5Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x-2, y+1, 0, 6);
            Ecp5Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x-2, y+1, 1, 6);
            Ecp5Bels::add_ioclk_bel(*rg, "TRELLIS_ECLKBUF", x-2, y, 0, 7);
            Ecp5Bels::add_ioclk_bel(*rg, "TRELLIS_ECLKBUF", x-2, y, 1, 7);
            Ecp5Bels::add_ioclk_bel(*rg, "TRELLIS_ECLKBUF", x-2, y+1, 0, 6);
            Ecp5Bels::add_ioclk_bel(*rg, "TRELLIS_ECLKBUF", x-2, y+1, 1, 6);
            Ecp5Bels::add_ioclk_bel(*rg, "DLLDELD", x-2, y-1, 0);
            Ecp5Bels::add_ioclk_bel(*rg, "DLLDELD", x-2, y, 0);
            Ecp5Bels::add_ioclk_bel(*rg, "DLLDELD", x-2, y+1, 0);
            Ecp5Bels::add_ioclk_bel(*rg, "DLLDELD", x-2, y+2, 0);
            Ecp5Bels::add_ioclk_bel(*rg, "ECLKBRIDGECS", x-2, y, 1);
            Ecp5Bels::add_ioclk_bel(*rg, "BRGECLKSYNC", x-2, y, 1);
        }
        if (tile->info.type == "ECLK_R") {
            Ecp5Bels::add_ioclk_bel(*rg, "CLKDIVF", x+2, y, 0);
            Ecp5Bels::add_ioclk_bel(*rg, "CLKDIVF", x+2, y, 1);
            Ecp5Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x+2, y, 0, 2);
            Ecp5Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x+2, y, 1, 2);
            Ecp5Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x+2, y+1, 0, 3);
            Ecp5Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x+2, y+1, 1, 3);
            Ecp5Bels::add_ioclk_bel(*rg, "TRELLIS_ECLKBUF", x+2, y, 0, 2);
            Ecp5Bels::add_ioclk_bel(*rg, "TRELLIS_ECLKBUF", x+2, y, 1, 2);
            Ecp5Bels::add_ioclk_bel(*rg, "TRELLIS_ECLKBUF", x+2, y+1, 0, 3);
            Ecp5Bels::add_ioclk_bel(*rg, "TRELLIS_ECLKBUF", x+2, y+1, 1, 3);
            Ecp5Bels::add_ioclk_bel(*rg, "DLLDELD", x+2, y-1, 0);
            Ecp5Bels::add_ioclk_bel(*rg, "DLLDELD", x+2, y, 0);
            Ecp5Bels::add_ioclk_bel(*rg, "DLLDELD", x+2, y+1, 0);
            Ecp5Bels::add_ioclk_bel(*rg, "DLLDELD", x+2, y+2, 0);
            Ecp5Bels::add_ioclk_bel(*rg, "ECLKBRIDGECS", x+2, y, 0);
            Ecp5Bels::add_ioclk_bel(*rg, "BRGECLKSYNC", x+2, y, 0);
        }
        if (tile->info.type == "DDRDLL_UL")
            Ecp5Bels::add_ioclk_bel(*rg, "DDRDLL", x-2, y-10, 0);
        if (tile->info.type == "DDRDLL_ULA")
            Ecp5Bels::add_ioclk_bel(*rg, "DDRDLL", x-2, y-13, 0);
        if (tile->info.type == "DDRDLL_UR")
            Ecp5Bels::add_ioclk_bel(*rg, "DDRDLL", x+2, y-10, 0);
        if (tile->info.type == "DDRDLL_URA")
            Ecp5Bels::add_ioclk_bel(*rg, "DDRDLL", x+2, y-13, 0);
        if (tile->info.type == "DDRDLL_LL")
            Ecp5Bels::add_ioclk_bel(*rg, "DDRDLL", x-2, y+13, 0);
        if (tile->info.type == "DDRDLL_LR")
            Ecp5Bels::add_ioclk_bel(*rg, "DDRDLL", x+2, y+13, 0);
        if (tile->info.type == "PICL0_DQS2" || tile->info.type == "PICR0_DQS2")
            Ecp5Bels::add_ioclk_bel(*rg, "DQSBUFM", x, y, 0);

    }
    return rg;
}

shared_ptr<RoutingGraph> Chip::get_routing_graph_machxo2()
{
    shared_ptr<RoutingGraph> rg(new RoutingGraph(*this));

    for (auto tile_entry : tiles) {
        shared_ptr<Tile> tile = tile_entry.second;
        //cout << "    Tile " << tile->info.name << endl;
        shared_ptr<TileBitDatabase> bitdb = get_tile_bitdata(TileLocator{info.family, info.name, tile->info.type});
        bitdb->add_routing(tile->info, *rg);
        int x, y;
        tie(y, x) = tile->info.get_row_col();

        // SLICE MachXO2Bels
        if (tile->info.type == "PLC")
            for (int z = 0; z < 4; z++)
                MachXO2Bels::add_lc(*rg, x, y, z);

        // PIO MachXO2Bels
        if (tile->info.type.find("PIC_L0") != string::npos || tile->info.type.find("PIC_LS0") != string::npos ||
            tile->info.type.find("PIC_T") != string::npos ||
            tile->info.type.find("PIC_R0") != string::npos || tile->info.type.find("PIC_RS0") != string::npos ||
            tile->info.type.find("PIC_B") != string::npos)
            for (int z = 0; z < 4; z++)
                MachXO2Bels::add_pio(*rg, x, y, z);

        // DCC/DCM MachXO2Bels
        if (tile->info.type.find("CENTER_EBR_CIB") != string::npos) {
          for (int z = 0; z < 8; z++)
              MachXO2Bels::add_dcc(*rg, x, y, z);
          for (int z = 6; z < 8; z++)
              // Start at z = 8, but names start at 6.
              MachXO2Bels::add_dcm(*rg, x, y, z, z + 2);
        }

        if (tile->info.type.find("CIB_CFG0") != string::npos) {
            MachXO2Bels::add_osch(*rg, x, y, 0);
        }
    }

    return rg;
}

// Global network funcs

bool GlobalRegion::matches(int row, int col) const {
    return (row >= y0 && row <= y1 && col >= x0 && col <= x1);
}

bool TapSegment::matches_left(int row, int col) const {
    UNUSED(row);
    return (col >= lx0 && col <= lx1);
}

bool TapSegment::matches_right(int row, int col) const {
    UNUSED(row);
    return (col >= rx0 && col <= rx1);
}

string Ecp5GlobalsInfo::get_quadrant(int row, int col) const {
    for (const auto &quad : quadrants) {
        if (quad.matches(row, col))
            return quad.name;
    }
    throw runtime_error(fmt("R" << row << "C" << col << " matches no globals quadrant"));
}

TapDriver Ecp5GlobalsInfo::get_tap_driver(int row, int col) const {
    for (const auto &seg : tapsegs) {
        if (seg.matches_left(row, col)) {
            TapDriver td;
            td.dir = TapDriver::LEFT;
            td.col = seg.tap_col;
            return td;
        }
        if (seg.matches_right(row, col)) {
            TapDriver td;
            td.dir = TapDriver::RIGHT;
            td.col = seg.tap_col;
            return td;
        }
    }
    throw runtime_error(fmt("R" << row << "C" << col << " matches no global TAP_DRIVE segment"));
}

pair<int, int> Ecp5GlobalsInfo::get_spine_driver(std::string quadrant, int col) {
    for (const auto &seg : spinesegs) {
        if (seg.quadrant == quadrant && seg.tap_col == col) {
            return make_pair(seg.spine_row, seg.spine_col);
        }
    }
    throw runtime_error(fmt(quadrant << "C" << col << " matches no global SPINE segment"));
}


}
