#include "Tile.hpp"
#include "Chip.hpp"
#include "Database.hpp"
#include "BitDatabase.hpp"
#include "TileConfig.hpp"
#include "Util.hpp"

namespace Trellis {
// Regexes to extract row/column from a tile name.
static const regex tile_rxcx_re(R"(R(\d+)C(\d+))");

// MachXO2-specific, in order of precedence (otherwise, e.g.
// CENTER_EBR matches r_regex)
static const regex tile_center_re(R"(CENTER(\d+))");
static const regex tile_centerb_re(R"(CENTER_B)");
static const regex tile_centert_re(R"(CENTER_T)");
static const regex tile_centerebr_re(R"(CENTER_EBR(\d+))");
static const regex tile_t_re(R"([A-Za-z0-9_]*T(\d+))");
static const regex tile_b_re(R"([A-Za-z0-9_]*B(\d+))");
static const regex tile_l_re(R"([A-Za-z0-9_]*L(\d+))");
static const regex tile_r_re(R"([A-Za-z0-9_]*R(\d+))");

// Given the zero-indexed max chip_size, return the zero-indexed
// center. Mainly for MachXO2, it is based on the location of the entry
// to global routing.
// TODO: Make const.
map<pair<int, int>, pair<int, int>> center_map = {
    // 256HC
    {make_pair(7, 9), make_pair(3, 4)},
    // 640HC
    {make_pair(8, 17), make_pair(3, 7)},
    // 1200HC
    {make_pair(12, 21), make_pair(6, 12)},
    // 2000HC
    {make_pair(15, 25), make_pair(8, 13)},
    // 4000HC
    {make_pair(22, 31), make_pair(11, 15)},
    // 7000HC
    {make_pair(26, 40), make_pair(13, 18)},
};

// Universal function to get a zero-indexed row/column pair.
pair<int, int> get_row_col_pair_from_chipsize(string name, pair<int, int> chip_size, int bias) {
    smatch m;

    // Special-cases... CENTER30 will match wrong regex. Only on 7000HC,
    // this position is a best-guess.
    if(name.find("CENTER30") != std::string::npos) {
        return make_pair(20, 29);
    } else if(regex_search(name, m, tile_rxcx_re)) {
        return make_pair(stoi(m.str(1)), stoi(m.str(2)) - bias);
    } else if(regex_search(name, m, tile_centert_re)) {
        return make_pair(0, center_map[chip_size].second);
    } else if(regex_search(name, m, tile_centerb_re)) {
        return make_pair(chip_size.first, center_map[chip_size].second);
    } else if(regex_search(name, m, tile_centerebr_re)) {
        // TODO: This may not apply to devices larger than 1200.
        return make_pair(center_map[chip_size].first, stoi(m.str(1)) - bias);
    } else if(regex_search(name, m, tile_center_re)) {
        return make_pair(stoi(m.str(1)), center_map[chip_size].second);
    } else if(regex_search(name, m, tile_t_re)) {
        return make_pair(0, stoi(m.str(1)) - bias);
    } else if(regex_search(name, m, tile_b_re)) {
        return make_pair(chip_size.first, stoi(m.str(1)) - bias);
    } else if(regex_search(name, m, tile_l_re)) {
        return make_pair(stoi(m.str(1)), 0);
    } else if(regex_search(name, m, tile_r_re)) {
        return make_pair(stoi(m.str(1)), chip_size.second);
    } else {
        throw runtime_error(fmt("Could not extract position from " << name));
    }
}

Tile::Tile(Trellis::TileInfo info, Trellis::Chip &parent) : info(info), cram(parent.cram.make_view(info.frame_offset,
                                                                                                   info.bit_offset,
                                                                                                   info.num_frames,
                                                                                                   info.bits_per_frame)) {}

string Tile::dump_config() const {
    shared_ptr<TileBitDatabase> bitdb = get_tile_bitdata(TileLocator(info.family, info.device, info.type));
    TileConfig cfg = bitdb->tile_cram_to_config(cram);
    known_bits = cfg.total_known_bits;
    unknown_bits = int(cfg.cunknowns.size());
    stringstream ss;
    ss << cfg;
    return ss.str();
}

void Tile::read_config(string config) {
    shared_ptr<TileBitDatabase> bitdb = get_tile_bitdata(TileLocator(info.family, info.device, info.type));
    stringstream ss(config);
    TileConfig tcfg;
    ss >> tcfg;
    bitdb->config_to_tile_cram(tcfg, cram);
}
}
