#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));
    }
    global_data = get_global_info(DeviceLocator{info.family, info.name});
}

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);
    }

    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 GlobalsInfo::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 GlobalsInfo::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> GlobalsInfo::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"));
}


}
