#include "DedupChipdb.hpp"
#include "Chip.hpp"

namespace Trellis {
namespace DDChipDb {

checksum_t LocationData::checksum() const
{
    pair<uint64_t, uint64_t> cs = make_pair(0, 0);
    const uint64_t magic1 = 0x9e3779b97f4a7c15ULL;
    const uint64_t magic2 = 0xf476452575661fbeULL;
    for (const auto &wire : wires) {
        cs.first = magic1 + std::hash<WireData>()(wire) + (cs.first << 12UL) + (cs.second >> 2UL);
        cs.second = magic2 + std::hash<WireData>()(wire) + (cs.second << 17UL) + (cs.first >> 1UL);
    }
    for (const auto &bel : bels) {
        cs.first = magic1 + std::hash<BelData>()(bel) + (cs.first << 12UL) + (cs.second >> 2UL);
        cs.second = magic2 + std::hash<BelData>()(bel) + (cs.second << 17UL) + (cs.first >> 1UL);
    }
    for (const auto &arc : arcs) {
        cs.first = magic1 + std::hash<DdArcData>()(arc) + (cs.first << 12UL) + (cs.second >> 2UL);
        cs.second = magic2 + std::hash<DdArcData>()(arc) + (cs.second << 17UL) + (cs.first >> 1UL);
    }
    return cs;
}

DedupChipdb::DedupChipdb()
{

}

DedupChipdb::DedupChipdb(const IdStore &base) : IdStore(base)
{}

shared_ptr<DedupChipdb> make_dedup_chipdb(Chip &chip, bool include_lutperm_pips)
{
    shared_ptr<RoutingGraph> graph = chip.get_routing_graph(include_lutperm_pips);
    for (auto &loc : graph->tiles) {
        const auto &td = loc.second;
        // Index bels, wires and arcs
        int bel_id = 0, wire_id = 0, arc_id = 0;
        for (auto &bel : td.bels) {
            RoutingId rid;
            rid.loc = loc.first;
            rid.id = bel.first;
            bel.second.cdb_id = bel_id++;
        }
        for (auto &wire : td.wires) {
            RoutingId rid;
            rid.loc = loc.first;
            rid.id = wire.first;
            wire.second.cdb_id  = wire_id++;
        }
        for (auto &arc : td.arcs) {
            RoutingId rid;
            rid.loc = loc.first;
            rid.id = arc.first;
            arc.second.cdb_id = arc_id++;
        }
    }
    shared_ptr<DedupChipdb> cdb = make_shared<DedupChipdb>(IdStore(*graph));
    for (const auto &loc : graph->tiles) {
        int x = loc.first.x, y = loc.first.y;
        LocationData ld;
        const auto &td = loc.second;
        for (const auto &bel : td.bels) {
            const RoutingBel &rb = bel.second;
            BelData bd;
            bd.name = rb.name;
            bd.type = rb.type;
            bd.z = rb.z;
            for (const auto &wire : rb.pins) {
                BelWire bw;
                bw.pin = wire.first;
                bw.wire = RelId{Location(wire.second.first.loc.x - x, wire.second.first.loc.y - y), graph->tiles.at(wire.second.first.loc).wires.at(wire.second.first.id).cdb_id};
                bw.dir = wire.second.second;
                bd.wires.push_back(bw);
            }
            ld.bels.push_back(bd);
        }

        for (const auto &arc : td.arcs) {
            const RoutingArc &ra = arc.second;
            DdArcData ad;
            ad.tiletype = ra.tiletype;
            ad.cls = ra.configurable ? ARC_STANDARD : ARC_FIXED;
            ad.delay = 1;
            ad.sinkWire = RelId{Location(ra.sink.loc.x - x, ra.sink.loc.y - y), graph->tiles.at(ra.sink.loc).wires.at(ra.sink.id).cdb_id};
            ad.srcWire = RelId{Location(ra.source.loc.x - x, ra.source.loc.y - y), graph->tiles.at(ra.source.loc).wires.at(ra.source.id).cdb_id};
            ad.lutperm_flags = ra.lutperm_flags;
            ld.arcs.push_back(ad);
        }

        for (const auto &wire : td.wires) {
            const RoutingWire &rw = wire.second;
            WireData wd;
            wd.name = rw.id;
            for (const auto &dh : rw.downhill)
                wd.arcsDownhill.insert(RelId{Location(dh.loc.x - x, dh.loc.y - y), graph->tiles.at(dh.loc).arcs.at(dh.id).cdb_id});
            for (const auto &uh : rw.uphill)
                wd.arcsUphill.insert(RelId{Location(uh.loc.x - x, uh.loc.y - y), graph->tiles.at(uh.loc).arcs.at(uh.id).cdb_id});
            for (const auto &bdh : rw.belsDownhill) {
                BelPort bp;
                bp.pin = bdh.second;
                bp.bel = RelId{Location(bdh.first.loc.x - x, bdh.first.loc.y - y), graph->tiles.at(bdh.first.loc).bels.at(bdh.first.id).cdb_id};
                wd.belPins.push_back(bp);
            }
            assert(rw.belsUphill.size() <= 1);
            if (rw.belsUphill.size() == 1) {
                const auto &buh = rw.belsUphill[0];
                BelPort uh;
                uh.bel = RelId{Location(buh.first.loc.x - x, buh.first.loc.y - y), graph->tiles.at(buh.first.loc).bels.at(buh.first.id).cdb_id};
                uh.pin = buh.second;
                wd.belPins.push_back(uh);
            }
            ld.wires.push_back(wd);
        }

        checksum_t cs = ld.checksum();
        if (cdb->locationTypes.find(cs) == cdb->locationTypes.end()) {
            cdb->locationTypes[cs] = ld;
        } else {
            if (!(ld == cdb->locationTypes[cs]))
                terminate();
        }
        cdb->typeAtLocation[loc.first] = cs;
    }

    return cdb;
}

LocationData DedupChipdb::get_cs_data(checksum_t id) {
    return locationTypes.at(id);
}

}
}
