/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "nextpnr.h"
#include <boost/algorithm/string.hpp>
#include "design_utils.h"
#include "log.h"

NEXTPNR_NAMESPACE_BEGIN

assertion_failure::assertion_failure(std::string msg, std::string expr_str, std::string filename, int line)
        : runtime_error("Assertion failure: " + msg + " (" + filename + ":" + std::to_string(line) + ")"), msg(msg),
          expr_str(expr_str), filename(filename), line(line)
{
    log_flush();
}

void IdString::set(const BaseCtx *ctx, const std::string &s)
{
    auto it = ctx->idstring_str_to_idx->find(s);
    if (it == ctx->idstring_str_to_idx->end()) {
        index = ctx->idstring_idx_to_str->size();
        auto insert_rc = ctx->idstring_str_to_idx->insert({s, index});
        ctx->idstring_idx_to_str->push_back(&insert_rc.first->first);
    } else {
        index = it->second;
    }
}

const std::string &IdString::str(const BaseCtx *ctx) const { return *ctx->idstring_idx_to_str->at(index); }

const char *IdString::c_str(const BaseCtx *ctx) const { return str(ctx).c_str(); }

void IdString::initialize_add(const BaseCtx *ctx, const char *s, int idx)
{
    NPNR_ASSERT(ctx->idstring_str_to_idx->count(s) == 0);
    NPNR_ASSERT(int(ctx->idstring_idx_to_str->size()) == idx);
    auto insert_rc = ctx->idstring_str_to_idx->insert({s, idx});
    ctx->idstring_idx_to_str->push_back(&insert_rc.first->first);
}

TimingConstrObjectId BaseCtx::timingWildcardObject()
{
    TimingConstrObjectId id;
    id.index = 0;
    return id;
}

TimingConstrObjectId BaseCtx::timingClockDomainObject(NetInfo *clockDomain)
{
    NPNR_ASSERT(clockDomain->clkconstr != nullptr);
    if (clockDomain->clkconstr->domain_tmg_id != TimingConstrObjectId()) {
        return clockDomain->clkconstr->domain_tmg_id;
    } else {
        TimingConstraintObject obj;
        TimingConstrObjectId id;
        id.index = int(constraintObjects.size());
        obj.id = id;
        obj.type = TimingConstraintObject::CLOCK_DOMAIN;
        obj.entity = clockDomain->name;
        clockDomain->clkconstr->domain_tmg_id = id;
        constraintObjects.push_back(obj);
        return id;
    }
}

TimingConstrObjectId BaseCtx::timingNetObject(NetInfo *net)
{
    if (net->tmg_id != TimingConstrObjectId()) {
        return net->tmg_id;
    } else {
        TimingConstraintObject obj;
        TimingConstrObjectId id;
        id.index = int(constraintObjects.size());
        obj.id = id;
        obj.type = TimingConstraintObject::NET;
        obj.entity = net->name;
        constraintObjects.push_back(obj);
        net->tmg_id = id;
        return id;
    }
}

TimingConstrObjectId BaseCtx::timingCellObject(CellInfo *cell)
{
    if (cell->tmg_id != TimingConstrObjectId()) {
        return cell->tmg_id;
    } else {
        TimingConstraintObject obj;
        TimingConstrObjectId id;
        id.index = int(constraintObjects.size());
        obj.id = id;
        obj.type = TimingConstraintObject::CELL;
        obj.entity = cell->name;
        constraintObjects.push_back(obj);
        cell->tmg_id = id;
        return id;
    }
}

TimingConstrObjectId BaseCtx::timingPortObject(CellInfo *cell, IdString port)
{
    if (cell->ports.at(port).tmg_id != TimingConstrObjectId()) {
        return cell->ports.at(port).tmg_id;
    } else {
        TimingConstraintObject obj;
        TimingConstrObjectId id;
        id.index = int(constraintObjects.size());
        obj.id = id;
        obj.type = TimingConstraintObject::CELL_PORT;
        obj.entity = cell->name;
        obj.port = port;
        constraintObjects.push_back(obj);
        cell->ports.at(port).tmg_id = id;
        return id;
    }
}

Property::Property() : is_string(false), str(""), intval(0) {}

Property::Property(int64_t intval, int width) : is_string(false), intval(intval)
{
    str.reserve(width);
    for (int i = 0; i < width; i++)
        str.push_back((intval & (1ULL << i)) ? S1 : S0);
}

Property::Property(const std::string &strval) : is_string(true), str(strval), intval(0xDEADBEEF) {}

Property::Property(State bit) : is_string(false), str(std::string("") + char(bit)), intval(bit == S1) {}

std::string Property::to_string() const
{
    if (is_string) {
        std::string result = str;
        int state = 0;
        for (char c : str) {
            if (state == 0) {
                if (c == '0' || c == '1' || c == 'x' || c == 'z')
                    state = 0;
                else if (c == ' ')
                    state = 1;
                else
                    state = 2;
            } else if (state == 1 && c != ' ')
                state = 2;
        }
        if (state < 2)
            result += " ";
        return result;
    } else {
        return std::string(str.rbegin(), str.rend());
    }
}

Property Property::from_string(const std::string &s)
{
    Property p;

    size_t cursor = s.find_first_not_of("01xz");
    if (cursor == std::string::npos) {
        p.str = std::string(s.rbegin(), s.rend());
        p.is_string = false;
        p.update_intval();
    } else if (s.find_first_not_of(' ', cursor) == std::string::npos) {
        p = Property(s.substr(0, s.size() - 1));
    } else {
        p = Property(s);
    }
    return p;
}

void CellInfo::setParam(IdString name, std::string value) { params[name] = Property::from_string(value); }

void CellInfo::setAttr(IdString name, std::string value) { attrs[name] = Property::from_string(value); }

void BaseCtx::addConstraint(std::unique_ptr<TimingConstraint> constr)
{
    for (auto fromObj : constr->from)
        constrsFrom.emplace(fromObj, constr.get());
    for (auto toObj : constr->to)
        constrsTo.emplace(toObj, constr.get());
    IdString name = constr->name;
    constraints[name] = std::move(constr);
}

void BaseCtx::removeConstraint(IdString constrName)
{
    TimingConstraint *constr = constraints[constrName].get();
    for (auto fromObj : constr->from) {
        auto fromConstrs = constrsFrom.equal_range(fromObj);
        constrsFrom.erase(std::find(fromConstrs.first, fromConstrs.second, std::make_pair(fromObj, constr)));
    }
    for (auto toObj : constr->to) {
        auto toConstrs = constrsFrom.equal_range(toObj);
        constrsFrom.erase(std::find(toConstrs.first, toConstrs.second, std::make_pair(toObj, constr)));
    }
    constraints.erase(constrName);
}

const char *BaseCtx::nameOfBel(BelId bel) const
{
    const Context *ctx = getCtx();
    return ctx->getBelName(bel).c_str(ctx);
}

const char *BaseCtx::nameOfWire(WireId wire) const
{
    const Context *ctx = getCtx();
    return ctx->getWireName(wire).c_str(ctx);
}

const char *BaseCtx::nameOfPip(PipId pip) const
{
    const Context *ctx = getCtx();
    return ctx->getPipName(pip).c_str(ctx);
}

const char *BaseCtx::nameOfGroup(GroupId group) const
{
    const Context *ctx = getCtx();
    return ctx->getGroupName(group).c_str(ctx);
}

WireId Context::getNetinfoSourceWire(const NetInfo *net_info) const
{
    if (net_info->driver.cell == nullptr)
        return WireId();

    auto src_bel = net_info->driver.cell->bel;

    if (src_bel == BelId())
        return WireId();

    IdString driver_port = net_info->driver.port;

    auto driver_port_it = net_info->driver.cell->pins.find(driver_port);
    if (driver_port_it != net_info->driver.cell->pins.end())
        driver_port = driver_port_it->second;

    return getBelPinWire(src_bel, driver_port);
}

WireId Context::getNetinfoSinkWire(const NetInfo *net_info, const PortRef &user_info) const
{
    auto dst_bel = user_info.cell->bel;

    if (dst_bel == BelId())
        return WireId();

    IdString user_port = user_info.port;

    auto user_port_it = user_info.cell->pins.find(user_port);

    if (user_port_it != user_info.cell->pins.end())
        user_port = user_port_it->second;

    return getBelPinWire(dst_bel, user_port);
}

delay_t Context::getNetinfoRouteDelay(const NetInfo *net_info, const PortRef &user_info) const
{
#ifdef ARCH_ECP5
    if (net_info->is_global)
        return 0;
#endif

    if (net_info->wires.empty())
        return predictDelay(net_info, user_info);

    WireId src_wire = getNetinfoSourceWire(net_info);
    if (src_wire == WireId())
        return 0;

    WireId dst_wire = getNetinfoSinkWire(net_info, user_info);
    WireId cursor = dst_wire;
    delay_t delay = 0;

    while (cursor != WireId() && cursor != src_wire) {
        auto it = net_info->wires.find(cursor);

        if (it == net_info->wires.end())
            break;

        PipId pip = it->second.pip;
        if (pip == PipId())
            break;

        delay += getPipDelay(pip).maxDelay();
        delay += getWireDelay(cursor).maxDelay();
        cursor = getPipSrcWire(pip);
    }

    if (cursor == src_wire)
        return delay + getWireDelay(src_wire).maxDelay();

    return predictDelay(net_info, user_info);
}

static uint32_t xorshift32(uint32_t x)
{
    x ^= x << 13;
    x ^= x >> 17;
    x ^= x << 5;
    return x;
}

uint32_t Context::checksum() const
{
    uint32_t cksum = xorshift32(123456789);

    uint32_t cksum_nets_sum = 0;
    for (auto &it : nets) {
        auto &ni = *it.second;
        uint32_t x = 123456789;
        x = xorshift32(x + xorshift32(it.first.index));
        x = xorshift32(x + xorshift32(ni.name.index));
        if (ni.driver.cell)
            x = xorshift32(x + xorshift32(ni.driver.cell->name.index));
        x = xorshift32(x + xorshift32(ni.driver.port.index));
        x = xorshift32(x + xorshift32(getDelayChecksum(ni.driver.budget)));

        for (auto &u : ni.users) {
            if (u.cell)
                x = xorshift32(x + xorshift32(u.cell->name.index));
            x = xorshift32(x + xorshift32(u.port.index));
            x = xorshift32(x + xorshift32(getDelayChecksum(u.budget)));
        }

        uint32_t attr_x_sum = 0;
        for (auto &a : ni.attrs) {
            uint32_t attr_x = 123456789;
            attr_x = xorshift32(attr_x + xorshift32(a.first.index));
            for (char ch : a.second.str)
                attr_x = xorshift32(attr_x + xorshift32((int)ch));
            attr_x_sum += attr_x;
        }
        x = xorshift32(x + xorshift32(attr_x_sum));

        uint32_t wire_x_sum = 0;
        for (auto &w : ni.wires) {
            uint32_t wire_x = 123456789;
            wire_x = xorshift32(wire_x + xorshift32(getWireChecksum(w.first)));
            wire_x = xorshift32(wire_x + xorshift32(getPipChecksum(w.second.pip)));
            wire_x = xorshift32(wire_x + xorshift32(int(w.second.strength)));
            wire_x_sum += wire_x;
        }
        x = xorshift32(x + xorshift32(wire_x_sum));

        cksum_nets_sum += x;
    }
    cksum = xorshift32(cksum + xorshift32(cksum_nets_sum));

    uint32_t cksum_cells_sum = 0;
    for (auto &it : cells) {
        auto &ci = *it.second;
        uint32_t x = 123456789;
        x = xorshift32(x + xorshift32(it.first.index));
        x = xorshift32(x + xorshift32(ci.name.index));
        x = xorshift32(x + xorshift32(ci.type.index));

        uint32_t port_x_sum = 0;
        for (auto &p : ci.ports) {
            uint32_t port_x = 123456789;
            port_x = xorshift32(port_x + xorshift32(p.first.index));
            port_x = xorshift32(port_x + xorshift32(p.second.name.index));
            if (p.second.net)
                port_x = xorshift32(port_x + xorshift32(p.second.net->name.index));
            port_x = xorshift32(port_x + xorshift32(p.second.type));
            port_x_sum += port_x;
        }
        x = xorshift32(x + xorshift32(port_x_sum));

        uint32_t attr_x_sum = 0;
        for (auto &a : ci.attrs) {
            uint32_t attr_x = 123456789;
            attr_x = xorshift32(attr_x + xorshift32(a.first.index));
            for (char ch : a.second.str)
                attr_x = xorshift32(attr_x + xorshift32((int)ch));
            attr_x_sum += attr_x;
        }
        x = xorshift32(x + xorshift32(attr_x_sum));

        uint32_t param_x_sum = 0;
        for (auto &p : ci.params) {
            uint32_t param_x = 123456789;
            param_x = xorshift32(param_x + xorshift32(p.first.index));
            for (char ch : p.second.str)
                param_x = xorshift32(param_x + xorshift32((int)ch));
            param_x_sum += param_x;
        }
        x = xorshift32(x + xorshift32(param_x_sum));

        x = xorshift32(x + xorshift32(getBelChecksum(ci.bel)));
        x = xorshift32(x + xorshift32(ci.belStrength));

        uint32_t pin_x_sum = 0;
        for (auto &a : ci.pins) {
            uint32_t pin_x = 123456789;
            pin_x = xorshift32(pin_x + xorshift32(a.first.index));
            pin_x = xorshift32(pin_x + xorshift32(a.second.index));
            pin_x_sum += pin_x;
        }
        x = xorshift32(x + xorshift32(pin_x_sum));

        cksum_cells_sum += x;
    }
    cksum = xorshift32(cksum + xorshift32(cksum_cells_sum));

    return cksum;
}

void Context::check() const
{
    for (auto &n : nets) {
        auto ni = n.second.get();
        NPNR_ASSERT(n.first == ni->name);
        for (auto &w : ni->wires) {
            NPNR_ASSERT(ni == getBoundWireNet(w.first));
            if (w.second.pip != PipId()) {
                NPNR_ASSERT(w.first == getPipDstWire(w.second.pip));
                NPNR_ASSERT(ni == getBoundPipNet(w.second.pip));
            }
        }
        if (ni->driver.cell != nullptr)
            NPNR_ASSERT(ni->driver.cell->ports.at(ni->driver.port).net == ni);
        for (auto user : ni->users) {
            NPNR_ASSERT(user.cell->ports.at(user.port).net == ni);
        }
    }

    for (auto w : getWires()) {
        auto ni = getBoundWireNet(w);
        if (ni != nullptr) {
            NPNR_ASSERT(ni->wires.count(w));
        }
    }

    for (auto &c : cells) {
        auto ci = c.second.get();
        NPNR_ASSERT(c.first == ci->name);
        if (ci->bel != BelId())
            NPNR_ASSERT(getBoundBelCell(c.second->bel) == ci);
        for (auto &port : c.second->ports) {
            NetInfo *net = port.second.net;
            if (net != nullptr) {
                NPNR_ASSERT(nets.find(net->name) != nets.end());
                if (port.second.type == PORT_OUT) {
                    NPNR_ASSERT(net->driver.cell == c.second.get() && net->driver.port == port.first);
                } else if (port.second.type == PORT_IN) {
                    NPNR_ASSERT(std::count_if(net->users.begin(), net->users.end(), [&](const PortRef &pr) {
                                    return pr.cell == c.second.get() && pr.port == port.first;
                                }) == 1);
                }
            }
        }
    }
}

void BaseCtx::addClock(IdString net, float freq)
{
    std::unique_ptr<ClockConstraint> cc(new ClockConstraint());
    cc->period = getCtx()->getDelayFromNS(1000 / freq);
    cc->high = getCtx()->getDelayFromNS(500 / freq);
    cc->low = getCtx()->getDelayFromNS(500 / freq);
    if (!nets.count(net)) {
        log_warning("net '%s' does not exist in design, ignoring clock constraint\n", net.c_str(this));
    } else {
        nets.at(net)->clkconstr = std::move(cc);
        log_info("constraining clock net '%s' to %.02f MHz\n", net.c_str(this), freq);
    }
}

void BaseCtx::createRectangularRegion(IdString name, int x0, int y0, int x1, int y1)
{
    std::unique_ptr<Region> new_region(new Region());
    new_region->name = name;
    new_region->constr_bels = true;
    new_region->constr_pips = false;
    new_region->constr_wires = false;
    for (int x = x0; x <= x1; x++) {
        for (int y = y0; y <= y1; y++) {
            for (auto bel : getCtx()->getBelsByTile(x, y))
                new_region->bels.insert(bel);
        }
    }
    region[name] = std::move(new_region);
}

void BaseCtx::makeConnection(IdString netname, IdString cellname, IdString portname)
{
    NetInfo *net = nets[netname].get();
    CellInfo *cell = cells[cellname].get();
    connect_port(getCtx(), net, cell, portname);
}

void BaseCtx::addBelToRegion(IdString name, BelId bel) { region[name]->bels.insert(bel); }
void BaseCtx::constrainCellToRegion(IdString cell, IdString region_name)
{
    cells[cell]->region = region[region_name].get();
}
DecalXY BaseCtx::constructDecalXY(DecalId decal, float x, float y)
{
    DecalXY dxy;
    dxy.decal = decal;
    dxy.x = x;
    dxy.y = y;
    return dxy;
}

void BaseCtx::archInfoToAttributes()
{
    for (auto &cell : cells) {
        auto ci = cell.second.get();
        if (ci->bel != BelId()) {
            if (ci->attrs.find(id("BEL")) != ci->attrs.end()) {
                ci->attrs.erase(ci->attrs.find(id("BEL")));
            }
            ci->attrs[id("NEXTPNR_BEL")] = getCtx()->getBelName(ci->bel).str(this);
            ci->attrs[id("BEL_STRENGTH")] = (int)ci->belStrength;
        }
        if (ci->constr_x != ci->UNCONSTR)
            ci->attrs[id("CONSTR_X")] = ci->constr_x;
        if (ci->constr_y != ci->UNCONSTR)
            ci->attrs[id("CONSTR_Y")] = ci->constr_y;
        if (ci->constr_z != ci->UNCONSTR) {
            ci->attrs[id("CONSTR_Z")] = ci->constr_z;
            ci->attrs[id("CONSTR_ABS_Z")] = ci->constr_abs_z ? 1 : 0;
        }
        if (ci->constr_parent != nullptr)
            ci->attrs[id("CONSTR_PARENT")] = ci->constr_parent->name.str(this);
        if (!ci->constr_children.empty()) {
            std::string constr = "";
            for (auto &item : ci->constr_children) {
                if (!constr.empty())
                    constr += std::string(";");
                constr += item->name.c_str(this);
            }
            ci->attrs[id("CONSTR_CHILDREN")] = constr;
        }
    }
    for (auto &net : getCtx()->nets) {
        auto ni = net.second.get();
        std::string routing;
        bool first = true;
        for (auto &item : ni->wires) {
            if (!first)
                routing += ";";
            routing += getCtx()->getWireName(item.first).c_str(this);
            routing += ";";
            if (item.second.pip != PipId())
                routing += getCtx()->getPipName(item.second.pip).c_str(this);
            routing += ";" + std::to_string(item.second.strength);
            first = false;
        }
        ni->attrs[id("ROUTING")] = routing;
    }
}

void BaseCtx::attributesToArchInfo()
{
    for (auto &cell : cells) {
        auto ci = cell.second.get();
        auto val = ci->attrs.find(id("NEXTPNR_BEL"));
        if (val != ci->attrs.end()) {
            auto str = ci->attrs.find(id("BEL_STRENGTH"));
            PlaceStrength strength = PlaceStrength::STRENGTH_USER;
            if (str != ci->attrs.end())
                strength = (PlaceStrength)str->second.as_int64();

            BelId b = getCtx()->getBelByName(id(val->second.as_string()));
            getCtx()->bindBel(b, ci, strength);
        }

        val = ci->attrs.find(id("CONSTR_PARENT"));
        if (val != ci->attrs.end()) {
            auto parent = cells.find(id(val->second.str));
            if (parent != cells.end())
                ci->constr_parent = parent->second.get();
            else
                continue;
        }

        val = ci->attrs.find(id("CONSTR_X"));
        if (val != ci->attrs.end())
            ci->constr_x = val->second.as_int64();

        val = ci->attrs.find(id("CONSTR_Y"));
        if (val != ci->attrs.end())
            ci->constr_y = val->second.as_int64();

        val = ci->attrs.find(id("CONSTR_Z"));
        if (val != ci->attrs.end())
            ci->constr_z = val->second.as_int64();

        val = ci->attrs.find(id("CONSTR_ABS_Z"));
        if (val != ci->attrs.end())
            ci->constr_abs_z = val->second.as_int64() == 1;

        val = ci->attrs.find(id("CONSTR_PARENT"));
        if (val != ci->attrs.end()) {
            auto parent = cells.find(id(val->second.as_string()));
            if (parent != cells.end())
                ci->constr_parent = parent->second.get();
        }
        val = ci->attrs.find(id("CONSTR_CHILDREN"));
        if (val != ci->attrs.end()) {
            std::vector<std::string> strs;
            auto children = val->second.as_string();
            boost::split(strs, children, boost::is_any_of(";"));
            for (auto val : strs) {
                if (cells.count(id(val.c_str())))
                    ci->constr_children.push_back(cells.find(id(val.c_str()))->second.get());
            }
        }
    }
    for (auto &net : getCtx()->nets) {
        auto ni = net.second.get();
        auto val = ni->attrs.find(id("ROUTING"));
        if (val != ni->attrs.end()) {
            std::vector<std::string> strs;
            auto routing = val->second.as_string();
            boost::split(strs, routing, boost::is_any_of(";"));
            for (size_t i = 0; i < strs.size() / 3; i++) {
                std::string wire = strs[i * 3];
                std::string pip = strs[i * 3 + 1];
                PlaceStrength strength = (PlaceStrength)std::stoi(strs[i * 3 + 2]);
                if (pip.empty())
                    getCtx()->bindWire(getCtx()->getWireByName(id(wire)), ni, strength);
                else
                    getCtx()->bindPip(getCtx()->getPipByName(id(pip)), ni, strength);
            }
        }
    }
    getCtx()->assignArchInfo();
}

NEXTPNR_NAMESPACE_END
