/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com>
 *  Copyright (C) 2018  Serge Bazanski <q3k@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 <algorithm>
#include <assert.h>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <boost/functional/hash.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/thread.hpp>

#ifndef NEXTPNR_H
#define NEXTPNR_H

#ifdef NEXTPNR_NAMESPACE
#define NEXTPNR_NAMESPACE_PREFIX NEXTPNR_NAMESPACE::
#define NEXTPNR_NAMESPACE_BEGIN namespace NEXTPNR_NAMESPACE {
#define NEXTPNR_NAMESPACE_END }
#define USING_NEXTPNR_NAMESPACE using namespace NEXTPNR_NAMESPACE;
#else
#define NEXTPNR_NAMESPACE_PREFIX
#define NEXTPNR_NAMESPACE_BEGIN
#define NEXTPNR_NAMESPACE_END
#define USING_NEXTPNR_NAMESPACE
#endif

#if defined(__GNUC__) || defined(__clang__)
#define NPNR_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
#define NPNR_NORETURN __attribute__((noreturn))
#define NPNR_DEPRECATED __attribute__((deprecated))
#define NPNR_PACKED_STRUCT(...) __VA_ARGS__ __attribute__((packed))
#elif defined(_MSC_VER)
#define NPNR_ATTRIBUTE(...)
#define NPNR_NORETURN __declspec(noreturn)
#define NPNR_DEPRECATED __declspec(deprecated)
#define NPNR_PACKED_STRUCT(...) __pragma(pack(push, 1)) __VA_ARGS__ __pragma(pack(pop))
#else
#define NPNR_ATTRIBUTE(...)
#define NPNR_NORETURN
#define NPNR_DEPRECATED
#define NPNR_PACKED_STRUCT(...) __VA_ARGS__
#endif

NEXTPNR_NAMESPACE_BEGIN

class assertion_failure : public std::runtime_error
{
  public:
    assertion_failure(std::string msg, std::string expr_str, std::string filename, int line);

    std::string msg;
    std::string expr_str;
    std::string filename;
    int line;
};

NPNR_NORETURN
inline void assert_fail_impl(const char *message, const char *expr_str, const char *filename, int line)
{
    throw assertion_failure(message, expr_str, filename, line);
}

NPNR_NORETURN
inline void assert_fail_impl_str(std::string message, const char *expr_str, const char *filename, int line)
{
    throw assertion_failure(message, expr_str, filename, line);
}

#define NPNR_ASSERT(cond) (!(cond) ? assert_fail_impl(#cond, #cond, __FILE__, __LINE__) : (void)true)
#define NPNR_ASSERT_MSG(cond, msg) (!(cond) ? assert_fail_impl(msg, #cond, __FILE__, __LINE__) : (void)true)
#define NPNR_ASSERT_FALSE(msg) (assert_fail_impl(msg, "false", __FILE__, __LINE__))
#define NPNR_ASSERT_FALSE_STR(msg) (assert_fail_impl_str(msg, "false", __FILE__, __LINE__))

struct BaseCtx;
struct Context;

struct IdString
{
    int index;

    static void initialize_arch(const BaseCtx *ctx);

    static void initialize_add(const BaseCtx *ctx, const char *s, int idx);

    constexpr IdString(int index = 0) : index(index) {}

    void set(const BaseCtx *ctx, const std::string &s);

    IdString(const BaseCtx *ctx, const std::string &s) { set(ctx, s); }

    IdString(const BaseCtx *ctx, const char *s) { set(ctx, s); }

    const std::string &str(const BaseCtx *ctx) const;

    const char *c_str(const BaseCtx *ctx) const;

    bool operator<(const IdString &other) const { return index < other.index; }

    bool operator==(const IdString &other) const { return index == other.index; }

    bool operator!=(const IdString &other) const { return index != other.index; }

    bool empty() const { return index == 0; }
};

NEXTPNR_NAMESPACE_END

namespace std {
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX IdString>
{
    std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX IdString &obj) const noexcept
    {
        return std::hash<int>()(obj.index);
    }
};
} // namespace std

NEXTPNR_NAMESPACE_BEGIN

struct GraphicElement
{
    enum type_t
    {
        TYPE_NONE,
        TYPE_LINE,
        TYPE_ARROW,
        TYPE_BOX,
        TYPE_CIRCLE,
        TYPE_LABEL,

        TYPE_MAX
    } type = TYPE_NONE;

    enum style_t
    {
        STYLE_GRID,
        STYLE_FRAME,    // Static "frame". Contrast between STYLE_INACTIVE and STYLE_ACTIVE
        STYLE_HIDDEN,   // Only display when object is selected or highlighted
        STYLE_INACTIVE, // Render using low-contrast color
        STYLE_ACTIVE,   // Render using high-contast color

        // UI highlight groups
        STYLE_HIGHLIGHTED0,
        STYLE_HIGHLIGHTED1,
        STYLE_HIGHLIGHTED2,
        STYLE_HIGHLIGHTED3,
        STYLE_HIGHLIGHTED4,
        STYLE_HIGHLIGHTED5,
        STYLE_HIGHLIGHTED6,
        STYLE_HIGHLIGHTED7,

        STYLE_SELECTED,
        STYLE_HOVER,

        STYLE_MAX
    } style = STYLE_FRAME;

    float x1 = 0, y1 = 0, x2 = 0, y2 = 0, z = 0;
    std::string text;
    GraphicElement(){};
    GraphicElement(type_t type, style_t style, float x1, float y1, float x2, float y2, float z)
            : type(type), style(style), x1(x1), y1(y1), x2(x2), y2(y2), z(z){};
};

struct Loc
{
    int x = -1, y = -1, z = -1;

    Loc() {}
    Loc(int x, int y, int z) : x(x), y(y), z(z) {}

    bool operator==(const Loc &other) const { return (x == other.x) && (y == other.y) && (z == other.z); }
    bool operator!=(const Loc &other) const { return (x != other.x) || (y != other.y) || (z != other.z); }
};

struct TimingConstrObjectId
{
    int32_t index = -1;

    bool operator==(const TimingConstrObjectId &other) const { return index == other.index; }
    bool operator!=(const TimingConstrObjectId &other) const { return index != other.index; }
};

NEXTPNR_NAMESPACE_END

namespace std {
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX Loc>
{
    std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX Loc &obj) const noexcept
    {
        std::size_t seed = 0;
        boost::hash_combine(seed, hash<int>()(obj.x));
        boost::hash_combine(seed, hash<int>()(obj.y));
        boost::hash_combine(seed, hash<int>()(obj.z));
        return seed;
    }
};

template <> struct hash<NEXTPNR_NAMESPACE_PREFIX TimingConstrObjectId>
{
    std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX TimingConstrObjectId &obj) const noexcept
    {
        return hash<int>()(obj.index);
    }
};

} // namespace std

#include "archdefs.h"

NEXTPNR_NAMESPACE_BEGIN

struct DecalXY
{
    DecalId decal;
    float x = 0, y = 0;

    bool operator==(const DecalXY &other) const { return (decal == other.decal && x == other.x && y == other.y); }
};

struct BelPin
{
    BelId bel;
    IdString pin;
};

struct CellInfo;

struct Region
{
    IdString name;

    bool constr_bels = false;
    bool constr_wires = false;
    bool constr_pips = false;

    std::unordered_set<BelId> bels;
    std::unordered_set<WireId> wires;
    std::unordered_set<Loc> piplocs;
};

enum PlaceStrength
{
    STRENGTH_NONE = 0,
    STRENGTH_WEAK = 1,
    STRENGTH_STRONG = 2,
    STRENGTH_FIXED = 3,
    STRENGTH_LOCKED = 4,
    STRENGTH_USER = 5
};

struct PortRef
{
    CellInfo *cell = nullptr;
    IdString port;
    delay_t budget = 0;
};

struct PipMap
{
    PipId pip = PipId();
    PlaceStrength strength = STRENGTH_NONE;
};

struct Property
{
    enum State : char
    {
        S0 = '0',
        S1 = '1',
        Sx = 'x',
        Sz = 'z'
    };

    Property();
    Property(int64_t intval, int width = 32);
    Property(const std::string &strval);
    Property(State bit);
    Property &operator=(const Property &other) = default;

    bool is_string;

    // The string literal (for string values), or a string of [01xz] (for numeric values)
    std::string str;
    // The lower 64 bits (for numeric values), unused for string values
    int64_t intval;

    void update_intval()
    {
        intval = 0;
        for (int i = 0; i < int(str.size()); i++) {
            NPNR_ASSERT(str[i] == S0 || str[i] == S1 || str[i] == Sx || str[i] == Sz);
            if ((str[i] == S1) && i < 64)
                intval |= (1ULL << i);
        }
    }

    int64_t as_int64() const
    {
        NPNR_ASSERT(!is_string);
        return intval;
    }
    std::vector<bool> as_bits() const
    {
        std::vector<bool> result;
        result.reserve(str.size());
        NPNR_ASSERT(!is_string);
        for (auto c : str)
            result.push_back(c == S1);
        return result;
    }
    std::string as_string() const
    {
        NPNR_ASSERT(is_string);
        return str;
    }
    const char *c_str() const
    {
        NPNR_ASSERT(is_string);
        return str.c_str();
    }
    size_t size() const { return is_string ? 8 * str.size() : str.size(); }
    double as_double() const
    {
        NPNR_ASSERT(is_string);
        return std::stod(str);
    }
    bool as_bool() const
    {
        if (int(str.size()) <= 64)
            return intval != 0;
        else
            return std::any_of(str.begin(), str.end(), [](char c) { return c == S1; });
    }
    bool is_fully_def() const
    {
        return !is_string && std::all_of(str.begin(), str.end(), [](char c) { return c == S0 || c == S1; });
    }
    Property extract(int offset, int len, State padding = State::S0) const
    {
        Property ret;
        ret.is_string = false;
        ret.str.reserve(len);
        for (int i = offset; i < offset + len; i++)
            ret.str.push_back(i < int(str.size()) ? str[i] : padding);
        ret.update_intval();
        return ret;
    }
    // Convert to a string representation, escaping literal strings matching /^[01xz]* *$/ by adding a space at the end,
    // to disambiguate from binary strings
    std::string to_string() const;
    // Convert a string of four-value binary [01xz], or a literal string escaped according to the above rule
    // to a Property
    static Property from_string(const std::string &s);
};

inline bool operator==(const Property &a, const Property &b) { return a.is_string == b.is_string && a.str == b.str; }
inline bool operator!=(const Property &a, const Property &b) { return a.is_string != b.is_string || a.str != b.str; }

struct ClockConstraint;

struct NetInfo : ArchNetInfo
{
    IdString name;
    int32_t udata = 0;

    PortRef driver;
    std::vector<PortRef> users;
    std::unordered_map<IdString, Property> attrs;

    // wire -> uphill_pip
    std::unordered_map<WireId, PipMap> wires;

    std::unique_ptr<ClockConstraint> clkconstr;

    TimingConstrObjectId tmg_id;

    Region *region = nullptr;
};

enum PortType
{
    PORT_IN = 0,
    PORT_OUT = 1,
    PORT_INOUT = 2
};

struct PortInfo
{
    IdString name;
    NetInfo *net;
    PortType type;
    TimingConstrObjectId tmg_id;
};

struct CellInfo : ArchCellInfo
{
    IdString name, type;
    int32_t udata;

    std::unordered_map<IdString, PortInfo> ports;
    std::unordered_map<IdString, Property> attrs, params;

    BelId bel;
    PlaceStrength belStrength = STRENGTH_NONE;

    // cell_port -> bel_pin
    std::unordered_map<IdString, IdString> pins;

    // placement constraints
    CellInfo *constr_parent = nullptr;
    std::vector<CellInfo *> constr_children;
    const int UNCONSTR = INT_MIN;
    int constr_x = UNCONSTR;   // this.x - parent.x
    int constr_y = UNCONSTR;   // this.y - parent.y
    int constr_z = UNCONSTR;   // this.z - parent.z
    bool constr_abs_z = false; // parent.z := 0
    // parent.[xyz] := 0 when (constr_parent == nullptr)

    Region *region = nullptr;
    TimingConstrObjectId tmg_id;
};

enum TimingPortClass
{
    TMG_CLOCK_INPUT,     // Clock input to a sequential cell
    TMG_GEN_CLOCK,       // Generated clock output (PLL, DCC, etc)
    TMG_REGISTER_INPUT,  // Input to a register, with an associated clock (may also have comb. fanout too)
    TMG_REGISTER_OUTPUT, // Output from a register
    TMG_COMB_INPUT,      // Combinational input, no paths end here
    TMG_COMB_OUTPUT,     // Combinational output, no paths start here
    TMG_STARTPOINT,      // Unclocked primary startpoint, such as an IO cell output
    TMG_ENDPOINT,        // Unclocked primary endpoint, such as an IO cell input
    TMG_IGNORE,          // Asynchronous to all clocks, "don't care", and should be ignored (false path) for analysis
};

enum ClockEdge
{
    RISING_EDGE,
    FALLING_EDGE
};

struct TimingClockingInfo
{
    IdString clock_port; // Port name of clock domain
    ClockEdge edge;
    DelayInfo setup, hold; // Input timing checks
    DelayInfo clockToQ;    // Output clock-to-Q time
};

struct ClockConstraint
{
    DelayInfo high;
    DelayInfo low;
    DelayInfo period;

    TimingConstrObjectId domain_tmg_id;
};

struct TimingConstraintObject
{
    TimingConstrObjectId id;
    enum
    {
        ANYTHING,
        CLOCK_DOMAIN,
        NET,
        CELL,
        CELL_PORT
    } type;
    IdString entity; // Name of clock net; net or cell
    IdString port;   // Name of port on a cell
};

struct TimingConstraint
{
    IdString name;

    enum
    {
        FALSE_PATH,
        MIN_DELAY,
        MAX_DELAY,
        MULTICYCLE,
    } type;

    delay_t value;

    std::unordered_set<TimingConstrObjectId> from;
    std::unordered_set<TimingConstrObjectId> to;
};

inline bool operator==(const std::pair<const TimingConstrObjectId, TimingConstraint *> &a,
                       const std::pair<TimingConstrObjectId, TimingConstraint *> &b)
{
    return a.first == b.first && a.second == b.second;
}

struct DeterministicRNG
{
    uint64_t rngstate;

    DeterministicRNG() : rngstate(0x3141592653589793) {}

    uint64_t rng64()
    {
        // xorshift64star
        // https://arxiv.org/abs/1402.6246

        uint64_t retval = rngstate * 0x2545F4914F6CDD1D;

        rngstate ^= rngstate >> 12;
        rngstate ^= rngstate << 25;
        rngstate ^= rngstate >> 27;

        return retval;
    }

    int rng() { return rng64() & 0x3fffffff; }

    int rng(int n)
    {
        assert(n > 0);

        // round up to power of 2
        int m = n - 1;
        m |= (m >> 1);
        m |= (m >> 2);
        m |= (m >> 4);
        m |= (m >> 8);
        m |= (m >> 16);
        m += 1;

        while (1) {
            int x = rng64() & (m - 1);
            if (x < n)
                return x;
        }
    }

    void rngseed(uint64_t seed)
    {
        rngstate = seed ? seed : 0x3141592653589793;
        for (int i = 0; i < 5; i++)
            rng64();
    }

    template <typename T> void shuffle(std::vector<T> &a)
    {
        for (size_t i = 0; i != a.size(); i++) {
            size_t j = i + rng(a.size() - i);
            if (j > i)
                std::swap(a[i], a[j]);
        }
    }

    template <typename T> void sorted_shuffle(std::vector<T> &a)
    {
        std::sort(a.begin(), a.end());
        shuffle(a);
    }
};

struct BaseCtx
{
    // Lock to perform mutating actions on the Context.
    std::mutex mutex;
    boost::thread::id mutex_owner;

    // Lock to be taken by UI when wanting to access context - the yield()
    // method will lock/unlock it when its' released the main mutex to make
    // sure the UI is not starved.
    std::mutex ui_mutex;

    // ID String database.
    mutable std::unordered_map<std::string, int> *idstring_str_to_idx;
    mutable std::vector<const std::string *> *idstring_idx_to_str;

    // Project settings and config switches
    std::unordered_map<IdString, Property> settings;

    // Placed nets and cells.
    std::unordered_map<IdString, std::unique_ptr<NetInfo>> nets;
    std::unordered_map<IdString, std::unique_ptr<CellInfo>> cells;

    // Top-level ports
    std::unordered_map<IdString, PortInfo> ports;

    // Floorplanning regions
    std::unordered_map<IdString, std::unique_ptr<Region>> region;

    // Context meta data
    std::unordered_map<IdString, Property> attrs;

    BaseCtx()
    {
        idstring_str_to_idx = new std::unordered_map<std::string, int>;
        idstring_idx_to_str = new std::vector<const std::string *>;
        IdString::initialize_add(this, "", 0);
        IdString::initialize_arch(this);

        TimingConstraintObject wildcard;
        wildcard.id.index = 0;
        wildcard.type = TimingConstraintObject::ANYTHING;
        constraintObjects.push_back(wildcard);
    }

    ~BaseCtx()
    {
        delete idstring_str_to_idx;
        delete idstring_idx_to_str;
    }

    // Must be called before performing any mutating changes on the Ctx/Arch.
    void lock(void)
    {
        mutex.lock();
        mutex_owner = boost::this_thread::get_id();
    }

    void unlock(void)
    {
        NPNR_ASSERT(boost::this_thread::get_id() == mutex_owner);
        mutex.unlock();
    }

    // Must be called by the UI before rendering data. This lock will be
    // prioritized when processing code calls yield().
    void lock_ui(void)
    {
        ui_mutex.lock();
        mutex.lock();
    }

    void unlock_ui(void)
    {
        mutex.unlock();
        ui_mutex.unlock();
    }

    // Yield to UI by unlocking the main mutex, flashing the UI mutex and
    // relocking the main mutex. Call this when you're performing a
    // long-standing action while holding a lock to let the UI show
    // visualization updates.
    // Must be called with the main lock taken.
    void yield(void)
    {
        unlock();
        ui_mutex.lock();
        ui_mutex.unlock();
        lock();
    }

    IdString id(const std::string &s) const { return IdString(this, s); }

    IdString id(const char *s) const { return IdString(this, s); }

    Context *getCtx() { return reinterpret_cast<Context *>(this); }

    const Context *getCtx() const { return reinterpret_cast<const Context *>(this); }

    const char *nameOf(IdString name) const { return name.c_str(this); }

    template <typename T> const char *nameOf(const T *obj) const
    {
        if (obj == nullptr)
            return "";
        return obj->name.c_str(this);
    }

    const char *nameOfBel(BelId bel) const;
    const char *nameOfWire(WireId wire) const;
    const char *nameOfPip(PipId pip) const;
    const char *nameOfGroup(GroupId group) const;

    // --------------------------------------------------------------

    bool allUiReload = true;
    bool frameUiReload = false;
    std::unordered_set<BelId> belUiReload;
    std::unordered_set<WireId> wireUiReload;
    std::unordered_set<PipId> pipUiReload;
    std::unordered_set<GroupId> groupUiReload;

    void refreshUi() { allUiReload = true; }

    void refreshUiFrame() { frameUiReload = true; }

    void refreshUiBel(BelId bel) { belUiReload.insert(bel); }

    void refreshUiWire(WireId wire) { wireUiReload.insert(wire); }

    void refreshUiPip(PipId pip) { pipUiReload.insert(pip); }

    void refreshUiGroup(GroupId group) { groupUiReload.insert(group); }

    // --------------------------------------------------------------

    // Timing Constraint API

    // constraint name -> constraint
    std::unordered_map<IdString, std::unique_ptr<TimingConstraint>> constraints;
    // object ID -> object
    std::vector<TimingConstraintObject> constraintObjects;
    // object ID -> constraint
    std::unordered_multimap<TimingConstrObjectId, TimingConstraint *> constrsFrom;
    std::unordered_multimap<TimingConstrObjectId, TimingConstraint *> constrsTo;

    TimingConstrObjectId timingWildcardObject();
    TimingConstrObjectId timingClockDomainObject(NetInfo *clockDomain);
    TimingConstrObjectId timingNetObject(NetInfo *net);
    TimingConstrObjectId timingCellObject(CellInfo *cell);
    TimingConstrObjectId timingPortObject(CellInfo *cell, IdString port);

    void addConstraint(std::unique_ptr<TimingConstraint> constr);
    void removeConstraint(IdString constrName);

    // Intended to simplify Python API
    void addClock(IdString net, float freq);
    void createRectangularRegion(IdString name, int x0, int y0, int x1, int y1);
    void addBelToRegion(IdString name, BelId bel);
    void constrainCellToRegion(IdString cell, IdString region_name);

    // Workaround for lack of wrappable constructors
    DecalXY constructDecalXY(DecalId decal, float x, float y);

    void archInfoToAttributes();
    void attributesToArchInfo();
};

NEXTPNR_NAMESPACE_END

#include "arch.h"

NEXTPNR_NAMESPACE_BEGIN

struct Context : Arch, DeterministicRNG
{
    bool verbose = false;
    bool debug = false;
    bool force = false;

    Context(ArchArgs args) : Arch(args) {}

    // --------------------------------------------------------------

    WireId getNetinfoSourceWire(const NetInfo *net_info) const;
    WireId getNetinfoSinkWire(const NetInfo *net_info, const PortRef &sink) const;
    delay_t getNetinfoRouteDelay(const NetInfo *net_info, const PortRef &sink) const;

    // provided by router1.cc
    bool checkRoutedDesign() const;
    bool getActualRouteDelay(WireId src_wire, WireId dst_wire, delay_t *delay = nullptr,
                             std::unordered_map<WireId, PipId> *route = nullptr, bool useEstimate = true);

    // --------------------------------------------------------------

    uint32_t checksum() const;

    void check() const;
    void archcheck() const;

    template <typename T> T setting(const char *name, T defaultValue)
    {
        IdString new_id = id(name);
        auto found = settings.find(new_id);
        if (found != settings.end())
            return boost::lexical_cast<T>(found->second.is_string ? found->second.as_string()
                                                                  : std::to_string(found->second.as_int64()));
        else
            settings[id(name)] = std::to_string(defaultValue);

        return defaultValue;
    }

    template <typename T> T setting(const char *name) const
    {
        IdString new_id = id(name);
        auto found = settings.find(new_id);
        if (found != settings.end())
            return boost::lexical_cast<T>(found->second.is_string ? found->second.as_string()
                                                                  : std::to_string(found->second.as_int64()));
        else
            throw std::runtime_error("settings does not exists");
    }
};

NEXTPNR_NAMESPACE_END

#endif
