/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  SymbioticEDA
 *
 *  jsonparse.cc -- liberally copied from the yosys file of the same name by
 *
 *  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 "jsonparse.h"
#include <assert.h>
#include <fstream>
#include <iostream>
#include <iterator>
#include <log.h>
#include <map>
#include <string>
#include "nextpnr.h"

NEXTPNR_NAMESPACE_BEGIN

extern bool check_all_nets_driven(Context *ctx);

namespace JsonParser {

const bool json_debug = false;

typedef std::string string;

template <typename T> int GetSize(const T &obj) { return obj.size(); }

struct JsonNode
{
    char type; // S=String, N=Number, A=Array, D=Dict
    string data_string;
    int data_number;
    std::vector<JsonNode *> data_array;
    std::map<string, JsonNode *> data_dict;
    std::vector<string> data_dict_keys;

    JsonNode(std::istream &f, int &lineno)
    {
        type = 0;
        data_number = 0;

        while (1) {
            int ch = f.get();

            if (ch == EOF)
                log_error("Unexpected EOF in JSON file.\n");

            if (ch == '\n')
                lineno++;
            if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
                continue;

            if (ch == '\"') {
                type = 'S';

                while (1) {
                    ch = f.get();

                    if (ch == EOF)
                        log_error("Unexpected EOF in JSON string.\n");

                    if (ch == '\"')
                        break;

                    if (ch == '\\') {
                        int ch = f.get();

                        if (ch == EOF)
                            log_error("Unexpected EOF in JSON string.\n");
                    }

                    data_string += ch;
                }

                break;
            }

            if (('0' <= ch && ch <= '9') || ('-' == ch)) {
                type = 'N';
                if (ch == '-')
                    data_number = 0;
                else
                    data_number = ch - '0';
                data_string += ch;

                while (1) {
                    ch = f.get();

                    if (ch == EOF)
                        break;

                    if (ch == '.')
                        goto parse_real;

                    if (ch < '0' || '9' < ch) {
                        f.unget();
                        break;
                    }

                    data_number = data_number * 10 + (ch - '0');
                    data_string += ch;
                }

                if (data_string[0] == '-')
                    data_number = -data_number;
                data_string = "";
                break;

            parse_real:
                type = 'S';
                data_number = 0;
                data_string += ch;

                while (1) {
                    ch = f.get();

                    if (ch == EOF)
                        break;

                    if (ch < '0' || '9' < ch) {
                        f.unget();
                        break;
                    }

                    data_string += ch;
                }

                break;
            }

            if (ch == '[') {
                type = 'A';

                while (1) {
                    ch = f.get();

                    if (ch == EOF)
                        log_error("Unexpected EOF in JSON file.\n");

                    if (ch == '\n')
                        lineno++;
                    if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == ',')
                        continue;

                    if (ch == ']')
                        break;

                    f.unget();
                    data_array.push_back(new JsonNode(f, lineno));
                }

                break;
            }

            if (ch == '{') {
                type = 'D';

                while (1) {
                    ch = f.get();

                    if (ch == EOF)
                        log_error("Unexpected EOF in JSON file.\n");

                    if (ch == '\n')
                        lineno++;
                    if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == ',')
                        continue;

                    if (ch == '}')
                        break;

                    f.unget();
                    JsonNode key(f, lineno);

                    while (1) {
                        ch = f.get();

                        if (ch == EOF)
                            log_error("Unexpected EOF in JSON file.\n");

                        if (ch == '\n')
                            lineno++;
                        if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == ':')
                            continue;

                        f.unget();
                        break;
                    }

                    JsonNode *value = new JsonNode(f, lineno);

                    if (key.type != 'S')
                        log_error("Unexpected non-string key in JSON dict, line %d.\n", lineno);

                    data_dict[key.data_string] = value;
                    data_dict_keys.push_back(key.data_string);
                }

                break;
            }

            log_error("Unexpected character in JSON file, line %d: '%c'\n", lineno, ch);
        }
    }

    ~JsonNode()
    {
        for (auto it : data_array)
            delete it;
        for (auto &it : data_dict)
            delete it.second;
    }
};

inline Property json_parse_attr_param_value(JsonNode *node)
{
    Property value;

    if (node->type == 'S') {
        value = Property::from_string(node->data_string);
    } else if (node->type == 'N') {
        value = Property(node->data_number, 32);
    } else if (node->type == 'A') {
        log_error("JSON attribute or parameter value is an array.\n");
    } else if (node->type == 'D') {
        log_error("JSON attribute or parameter value is a dict.\n");
    } else {
        log_abort();
    }

    return value;
}

void ground_net(Context *ctx, NetInfo *net)
{
    std::unique_ptr<CellInfo> cell = std::unique_ptr<CellInfo>(new CellInfo);
    PortInfo port_info;
    PortRef port_ref;

    cell->name = ctx->id(net->name.str(ctx) + ".GND");
    cell->type = ctx->id("GND");

    port_info.name = ctx->id(cell->name.str(ctx) + "[]");
    port_info.net = net;
    port_info.type = PORT_OUT;

    port_ref.cell = cell.get();
    port_ref.port = port_info.name;

    net->driver = port_ref;

    cell->ports[port_info.name] = port_info;

    ctx->cells[cell->name] = std::move(cell);
}

void vcc_net(Context *ctx, NetInfo *net)
{
    std::unique_ptr<CellInfo> cell = std::unique_ptr<CellInfo>(new CellInfo);
    PortInfo port_info;
    PortRef port_ref;

    cell->name = ctx->id(net->name.str(ctx) + ".VCC");
    cell->type = ctx->id("VCC");

    port_info.name = ctx->id(cell->name.str(ctx) + "[]");
    port_info.net = net;
    port_info.type = PORT_OUT;

    port_ref.cell = cell.get();
    port_ref.port = port_info.name;

    net->driver = port_ref;

    cell->ports[port_info.name] = port_info;

    ctx->cells[cell->name] = std::move(cell);
}

//
// is_blackbox
//
// Checks the JsonNode for an attributes dictionary, with a "blackbox" entry.
// An item is deemed to be a blackbox if this entry exists and if its
// value is not zero.  If the item is a black box, this routine will return
// true, false otherwise
bool is_blackbox(JsonNode *node)
{
    JsonNode *attr_node, *bbox_node = nullptr, *wbox_node = nullptr;

    if (node->data_dict.count("attributes") == 0)
        return false;
    attr_node = node->data_dict.at("attributes");
    if (attr_node == NULL)
        return false;
    if (attr_node->type != 'D')
        return false;
    if (GetSize(attr_node->data_dict) == 0)
        return false;
    if (attr_node->data_dict.count("blackbox"))
        bbox_node = attr_node->data_dict.at("blackbox");
    if (attr_node->data_dict.count("whitebox"))
        wbox_node = attr_node->data_dict.at("whitebox");
    if (bbox_node == NULL && wbox_node == NULL)
        return false;
    if (bbox_node && bbox_node->type != 'N')
        log_error("JSON module blackbox attribute value is not a number\n");
    if (bbox_node && bbox_node->data_number == 0)
        return false;
    if (wbox_node && wbox_node->type != 'N')
        log_error("JSON module whitebox attribute value is not a number\n");
    if (wbox_node && wbox_node->data_number == 0)
        return false;
    return true;
}

void json_import_cell_params(Context *ctx, string &modname, CellInfo *cell, JsonNode *param_node,
                             std::unordered_map<IdString, Property> *dest, int param_id)
{
    //
    JsonNode *param;
    IdString pId;
    //
    param = param_node->data_dict.at(param_node->data_dict_keys[param_id]);

    pId = ctx->id(param_node->data_dict_keys[param_id]);
    (*dest)[pId] = json_parse_attr_param_value(param);

    if (json_debug)
        log_info("    Added parameter \'%s\'=%s to cell \'%s\' "
                 "of module \'%s\'\n",
                 pId.c_str(ctx), cell->params[pId].as_string().c_str(), cell->name.c_str(ctx), modname.c_str());
}

void json_import_net_attrib(Context *ctx, string &modname, NetInfo *net, JsonNode *param_node,
                            std::unordered_map<IdString, Property> *dest, int param_id)
{
    //
    JsonNode *param;
    IdString pId;
    //
    param = param_node->data_dict.at(param_node->data_dict_keys[param_id]);

    pId = ctx->id(param_node->data_dict_keys[param_id]);
    (*dest)[pId] = json_parse_attr_param_value(param);

    if (json_debug)
        log_info("    Added parameter \'%s\'=%s to net \'%s\' "
                 "of module \'%s\'\n",
                 pId.c_str(ctx), net->attrs[pId].as_string().c_str(), net->name.c_str(ctx), modname.c_str());
}

void json_import_top_attrib(Context *ctx, string &modname, JsonNode *param_node,
                            std::unordered_map<IdString, Property> *dest, int param_id)
{
    //
    JsonNode *param;
    IdString pId;
    //
    param = param_node->data_dict.at(param_node->data_dict_keys[param_id]);

    pId = ctx->id(param_node->data_dict_keys[param_id]);
    (*dest)[pId] = json_parse_attr_param_value(param);

    if (json_debug)
        log_info("    Added parameter \'%s\'=%s module \'%s\'\n", pId.c_str(ctx), (*dest)[pId].as_string().c_str(),
                 modname.c_str());
}

static int const_net_idx = 0;

template <typename F>
void json_import_ports(Context *ctx, const string &modname, const std::vector<IdString> &netnames,
                       const string &obj_name, const string &port_name, JsonNode *dir_node, JsonNode *wire_group_node,
                       bool upto, int start_offset, F visitor)
{
    // Examine a port of a cell or the design. For every bit of the port,
    // the connected net will be processed and `visitor` will be called
    // with (PortType dir, std::string name, NetInfo *net)
    assert(dir_node);

    if (json_debug)
        log_info("    Examining port %s, node %s\n", port_name.c_str(), obj_name.c_str());

    if (!wire_group_node)
        log_error("JSON no connection match "
                  "for port_direction \'%s\' of node \'%s\' "
                  "in module \'%s\'\n",
                  port_name.c_str(), obj_name.c_str(), modname.c_str());

    assert(wire_group_node);

    assert(dir_node->type == 'S');
    assert(wire_group_node->type == 'A');

    PortInfo port_info;

    port_info.name = ctx->id(port_name);
    if (dir_node->data_string.compare("input") == 0)
        port_info.type = PORT_IN;
    else if (dir_node->data_string.compare("output") == 0)
        port_info.type = PORT_OUT;
    else if (dir_node->data_string.compare("inout") == 0)
        port_info.type = PORT_INOUT;
    else
        log_error("JSON unknown port direction \'%s\' in node \'%s\' "
                  "of module \'%s\'\n",
                  dir_node->data_string.c_str(), obj_name.c_str(), modname.c_str());
    //
    // Find an update, or create a net to connect
    // to this port.
    //
    NetInfo *this_net = nullptr;
    bool is_bus;

    //
    // If this port references a bus, then there will be multiple nets
    // connected to it, all specified as part of an array.
    //
    is_bus = (wire_group_node->data_array.size() > 1);

    // Now loop through all of the connections to this port.
    if (wire_group_node->data_array.size() == 0) {
        //
        // There is/are no connections to this port.
        //
        // Create the port, but leave the net NULL

        visitor(port_info.type, port_info.name.str(ctx), nullptr);

        if (json_debug)
            log_info("      Port \'%s\' has no connection in \'%s\'\n", port_info.name.c_str(ctx), obj_name.c_str());

    } else
        for (int index = 0; index < int(wire_group_node->data_array.size()); index++) {
            //
            JsonNode *wire_node;
            PortInfo this_port;
            IdString net_id;
            //
            wire_node = wire_group_node->data_array[index];
            //
            // Pick a name for this port
            int ndx = index + start_offset;
            if (upto)
                ndx = start_offset + wire_group_node->data_array.size() - index - 1;
            if (is_bus)
                this_port.name = ctx->id(port_info.name.str(ctx) + "[" + std::to_string(ndx) + "]");
            else
                this_port.name = port_info.name;
            this_port.type = port_info.type;

            if (wire_node->type == 'N') {
                int net_num;

                // A simple net, specified by a number
                net_num = wire_node->data_number;
                if (net_num < int(netnames.size()))
                    net_id = netnames.at(net_num);
                else
                    net_id = ctx->id(std::to_string(net_num));
                if (ctx->nets.count(net_id) == 0) {
                    // The net doesn't exist in the design (yet)
                    // Create in now

                    if (json_debug)
                        log_info("      Generating a new net, \'%d\'\n", net_num);

                    std::unique_ptr<NetInfo> net = std::unique_ptr<NetInfo>(new NetInfo());
                    net->name = net_id;
                    net->driver.cell = NULL;
                    net->driver.port = IdString();
                    ctx->nets[net_id] = std::move(net);

                    this_net = ctx->nets[net_id].get();
                } else {
                    //
                    // The net already exists within the design.
                    // We'll connect to it
                    //
                    this_net = ctx->nets[net_id].get();
                    if (json_debug)
                        log_info("      Reusing net \'%s\', id \'%s\', "
                                 "with driver \'%s\'\n",
                                 this_net->name.c_str(ctx), net_id.c_str(ctx),
                                 (this_net->driver.cell != NULL) ? this_net->driver.port.c_str(ctx) : "NULL");
                }

            } else if (wire_node->type == 'S') {
                // Strings are only used to drive wires for the fixed
                // values "0", "1", and "x".  Handle those constant
                // values here.
                //
                // Constants always get their own new net
                std::unique_ptr<NetInfo> net = std::unique_ptr<NetInfo>(new NetInfo());
                net->name = ctx->id("$const_" + std::to_string(const_net_idx++));

                if (wire_node->data_string.compare(string("0")) == 0) {

                    if (json_debug)
                        log_info("      Generating a constant "
                                 "zero net\n");
                    ground_net(ctx, net.get());

                } else if (wire_node->data_string.compare(string("1")) == 0) {

                    if (json_debug)
                        log_info("      Generating a constant "
                                 "one  net\n");
                    vcc_net(ctx, net.get());

                } else if (wire_node->data_string.compare(string("x")) == 0) {
                    ground_net(ctx, net.get());
                } else
                    log_error("      Unknown fixed type wire node "
                              "value, \'%s\'\n",
                              wire_node->data_string.c_str());
                IdString n = net->name;
                ctx->nets[net->name] = std::move(net);
                this_net = ctx->nets[n].get();
            }

            if (json_debug)
                log_info("    Inserting port \'%s\' into cell \'%s\'\n", this_port.name.c_str(ctx), obj_name.c_str());
            visitor(this_port.type, this_port.name.str(ctx), this_net);
        }
}

void json_import_cell(Context *ctx, string modname, const std::vector<IdString> &netnames, JsonNode *cell_node,
                      string cell_name)
{
    JsonNode *cell_type, *param_node, *attr_node;

    cell_type = cell_node->data_dict.at("type");
    if (cell_type == NULL)
        return;

    std::unique_ptr<CellInfo> cell = std::unique_ptr<CellInfo>(new CellInfo);

    cell->name = ctx->id(cell_name);
    assert(cell_type->type == 'S');
    cell->type = ctx->id(cell_type->data_string);
    // No BEL assignment here/yet

    if (json_debug)
        log_info("  Processing %s $ %s\n", modname.c_str(), cell->name.c_str(ctx));

    param_node = cell_node->data_dict.at("parameters");
    if (param_node->type != 'D')
        log_error("JSON parameter list of \'%s\' is not a data dictionary\n", cell->name.c_str(ctx));

    //
    // Loop through all parameters, adding them into the
    // design to annotate the cell
    //
    for (int paramid = 0; paramid < GetSize(param_node->data_dict_keys); paramid++) {

        json_import_cell_params(ctx, modname, cell.get(), param_node, &cell->params, paramid);
    }

    attr_node = cell_node->data_dict.at("attributes");
    if (attr_node->type != 'D')
        log_error("JSON attribute list of \'%s\' is not a data dictionary\n", cell->name.c_str(ctx));

    //
    // Loop through all attributes, adding them into the
    // design to annotate the cell
    //
    for (int attrid = 0; attrid < GetSize(attr_node->data_dict_keys); attrid++) {

        json_import_cell_params(ctx, modname, cell.get(), attr_node, &cell->attrs, attrid);
    }

    //
    // Now connect the ports of this module.  The ports are defined by
    // both the port directions node as well as the connections node.
    // Both should contain dictionaries having the same keys.
    //

    JsonNode *pdir_node = NULL;
    if (cell_node->data_dict.count("port_directions") > 0) {

        pdir_node = cell_node->data_dict.at("port_directions");
        if (pdir_node->type != 'D')
            log_error("JSON port_directions node of \'%s\' "
                      "in module \'%s\' is not a "
                      "dictionary\n",
                      cell->name.c_str(ctx), modname.c_str());

    } else if (cell_node->data_dict.count("ports") > 0) {
        pdir_node = cell_node->data_dict.at("ports");
        if (pdir_node->type != 'D')
            log_error("JSON ports node of \'%s\' "
                      "in module \'%s\' is not a "
                      "dictionary\n",
                      cell->name.c_str(ctx), modname.c_str());
    }

    JsonNode *connections = cell_node->data_dict.at("connections");
    if (connections->type != 'D')
        log_error("JSON connections node of \'%s\' "
                  "in module \'%s\' is not a "
                  "dictionary\n",
                  cell->name.c_str(ctx), modname.c_str());

    if (GetSize(pdir_node->data_dict_keys) != GetSize(connections->data_dict_keys))
        log_error("JSON number of connections doesnt "
                  "match number of ports in node \'%s\' "
                  "of module \'%s\'\n",
                  cell->name.c_str(ctx), modname.c_str());

    //
    // Loop through all of the ports of this logic element
    //
    for (int portid = 0; portid < GetSize(pdir_node->data_dict_keys); portid++) {
        //
        string port_name;
        JsonNode *dir_node, *wire_group_node;
        //

        port_name = pdir_node->data_dict_keys[portid];
        dir_node = pdir_node->data_dict.at(port_name);
        wire_group_node = connections->data_dict.at(port_name);

        json_import_ports(ctx, modname, netnames, cell->name.str(ctx), port_name, dir_node, wire_group_node, false, 0,
                          [&cell, ctx](PortType type, const std::string &name, NetInfo *net) {
                              cell->ports[ctx->id(name)] = PortInfo{ctx->id(name), net, type};
                              PortRef pr;
                              pr.cell = cell.get();
                              pr.port = ctx->id(name);
                              if (net != nullptr) {
                                  if (type == PORT_IN || type == PORT_INOUT) {
                                      net->users.push_back(pr);
                                  } else if (type == PORT_OUT) {
                                      if (net->driver.cell != nullptr)
                                          log_error("multiple drivers on net '%s' (%s.%s and %s.%s)\n",
                                                    net->name.c_str(ctx), net->driver.cell->name.c_str(ctx),
                                                    net->driver.port.c_str(ctx), pr.cell->name.c_str(ctx),
                                                    pr.port.c_str(ctx));
                                      net->driver = pr;
                                  }
                              }
                          });
    }

    ctx->cells[cell->name] = std::move(cell);
    // check_all_nets_driven(ctx);
}

static void insert_iobuf(Context *ctx, NetInfo *net, PortType type, const string &name)
{
    // Instantiate a architecture-independent IO buffer connected to a given
    // net, of a given type, and named after the IO port.
    //
    // During packing, this generic IO buffer will be converted to an
    // architecure primitive.
    //
    if (ctx->settings.find(ctx->id("synth")) == ctx->settings.end()) {
        std::unique_ptr<CellInfo> iobuf = std::unique_ptr<CellInfo>(new CellInfo());
        iobuf->name = ctx->id(name);
        std::copy(net->attrs.begin(), net->attrs.end(), std::inserter(iobuf->attrs, iobuf->attrs.begin()));
        if (type == PORT_IN) {
            if (ctx->verbose)
                log_info("processing input port %s\n", name.c_str());
            iobuf->type = ctx->id("$nextpnr_ibuf");
            iobuf->ports[ctx->id("O")] = PortInfo{ctx->id("O"), net, PORT_OUT};
            // Special case: input, etc, directly drives inout
            if (net->driver.cell != nullptr) {
                if (net->driver.cell->type != ctx->id("$nextpnr_iobuf"))
                    log_error("Top-level input '%s' also driven by %s.%s.\n", name.c_str(),
                              net->driver.cell->name.c_str(ctx), net->driver.port.c_str(ctx));
                net = net->driver.cell->ports.at(ctx->id("I")).net;
            }
            assert(net->driver.cell == nullptr);
            net->driver.port = ctx->id("O");
            net->driver.cell = iobuf.get();
        } else if (type == PORT_OUT) {
            if (ctx->verbose)
                log_info("processing output port %s\n", name.c_str());
            iobuf->type = ctx->id("$nextpnr_obuf");
            iobuf->ports[ctx->id("I")] = PortInfo{ctx->id("I"), net, PORT_IN};
            PortRef ref;
            ref.cell = iobuf.get();
            ref.port = ctx->id("I");
            net->users.push_back(ref);
        } else if (type == PORT_INOUT) {
            if (ctx->verbose)
                log_info("processing inout port %s\n", name.c_str());
            iobuf->type = ctx->id("$nextpnr_iobuf");
            iobuf->ports[ctx->id("I")] = PortInfo{ctx->id("I"), nullptr, PORT_IN};

            // Split the input and output nets for bidir ports
            std::unique_ptr<NetInfo> net2 = std::unique_ptr<NetInfo>(new NetInfo());
            net2->name = ctx->id("$" + net->name.str(ctx) + "$iobuf_i");
            net2->driver = net->driver;
            if (net->driver.cell != nullptr) {
                net2->driver.cell->ports[net2->driver.port].net = net2.get();
                net->driver.cell = nullptr;
            }
            iobuf->ports[ctx->id("I")].net = net2.get();
            PortRef ref;
            ref.cell = iobuf.get();
            ref.port = ctx->id("I");
            net2->users.push_back(ref);
            ctx->nets[net2->name] = std::move(net2);

            iobuf->ports[ctx->id("O")] = PortInfo{ctx->id("O"), net, PORT_OUT};
            assert(net->driver.cell == nullptr);
            net->driver.port = ctx->id("O");
            net->driver.cell = iobuf.get();
        } else {
            assert(false);
        }
        ctx->cells[iobuf->name] = std::move(iobuf);
    }

    PortInfo pinfo;
    pinfo.name = ctx->id(name);
    pinfo.net = net;
    pinfo.type = type;
    ctx->ports[pinfo.name] = pinfo;
}

void json_import_toplevel_port(Context *ctx, const string &modname, const std::vector<IdString> &netnames,
                               const string &portname, JsonNode *node)
{
    JsonNode *dir_node = node->data_dict.at("direction");
    JsonNode *nets_node = node->data_dict.at("bits");
    bool upto = false;
    int start_offset = 0;
    if (node->data_dict.count("upto") != 0) {
        JsonNode *val = node->data_dict.at("upto");
        if (val->type == 'N')
            upto = val->data_number != 0;
    }
    if (node->data_dict.count("offset") != 0) {
        JsonNode *val = node->data_dict.at("offset");
        if (val->type == 'N')
            start_offset = val->data_number;
    }
    json_import_ports(
            ctx, modname, netnames, "Top Level IO", portname, dir_node, nets_node, upto, start_offset,
            [ctx](PortType type, const std::string &name, NetInfo *net) { insert_iobuf(ctx, net, type, name); });
}

void json_import(Context *ctx, string modname, JsonNode *node)
{
    if (is_blackbox(node))
        return;

    log_info("Importing module %s\n", modname.c_str());
    ctx->attrs[ctx->id("module")] = modname;
    JsonNode *attr_node = node->data_dict.at("attributes");
    for (int attrid = 0; attrid < GetSize(attr_node->data_dict_keys); attrid++) {
        json_import_top_attrib(ctx, modname, attr_node, &ctx->attrs, attrid);
    }

    JsonNode *ports_parent = nullptr;
    if (node->data_dict.count("ports") > 0)
        ports_parent = node->data_dict.at("ports");

    // Multiple labels might refer to the same net. For now we resolve conflicts thus:
    //  - (toplevel) ports are always preferred
    //  - names with fewer $ are always prefered
    //  - between equal $ counts, fewer .s are prefered
    //  - ties are resolved alphabetically
    auto prefer_netlabel = [ports_parent](const std::string &a, const std::string &b) {
        if (ports_parent != nullptr) {
            if (ports_parent->data_dict.count(a))
                return true;
            if (ports_parent->data_dict.count(b))
                return false;
        }
        if (b.empty())
            return true;
        long a_dollars = std::count(a.begin(), a.end(), '$'), b_dollars = std::count(b.begin(), b.end(), '$');
        if (a_dollars < b_dollars)
            return true;
        else if (a_dollars > b_dollars)
            return false;
        long a_dots = std::count(a.begin(), a.end(), '.'), b_dots = std::count(b.begin(), b.end(), '.');
        if (a_dots < b_dots)
            return true;
        else if (a_dots > b_dots)
            return false;
        return a < b;
    };

    // Import netnames
    std::vector<std::vector<std::string>> netlabels;
    if (node->data_dict.count("netnames")) {
        JsonNode *cell_parent = node->data_dict.at("netnames");
        for (int nnid = 0; nnid < GetSize(cell_parent->data_dict_keys); nnid++) {
            JsonNode *here;

            here = cell_parent->data_dict.at(cell_parent->data_dict_keys[nnid]);
            std::string basename = cell_parent->data_dict_keys[nnid];
            bool upto = false;
            int start_offset = 0;
            if (here->data_dict.count("upto") != 0) {
                JsonNode *val = here->data_dict.at("upto");
                if (val->type == 'N')
                    upto = val->data_number != 0;
            }
            if (here->data_dict.count("offset") != 0) {
                JsonNode *val = here->data_dict.at("offset");
                if (val->type == 'N')
                    start_offset = val->data_number;
            }
            if (here->data_dict.count("bits")) {
                JsonNode *bits = here->data_dict.at("bits");
                assert(bits->type == 'A');
                size_t num_bits = bits->data_array.size();
                for (size_t i = 0; i < num_bits; i++) {
                    int netid = bits->data_array.at(i)->data_number;
                    if (netid >= int(netlabels.size()))
                        netlabels.resize(netid + 1);
                    int ndx = i + start_offset;
                    if (upto)
                        ndx = start_offset + num_bits - i - 1;
                    std::string name =
                            basename + (num_bits == 1 ? "" : std::string("[") + std::to_string(ndx) + std::string("]"));
                    netlabels.at(netid).push_back(name);
                }
            }
        }
    }
    std::vector<IdString> netids;
    for (size_t i = 0; i < netlabels.size(); i++) {
        auto &labels = netlabels.at(i);
        if (labels.empty()) {
            // Backup for unnamed nets (not sure if these should actually happen)
            netids.push_back(ctx->id("$nextpnr$unknown_netname$" + std::to_string(i)));
        } else {
            // Pick a primary name for the net according to a simple heuristic
            std::string pref = labels.at(0);
            for (size_t j = 1; j < labels.size(); j++)
                if (prefer_netlabel(labels.at(j), pref))
                    pref = labels.at(j);
            netids.push_back(ctx->id(pref));
        }
    }
    if (node->data_dict.count("cells")) {
        JsonNode *cell_parent = node->data_dict.at("cells");
        //
        //
        // Loop through all of the logic elements in a flattened design
        //
        //
        for (int cellid = 0; cellid < GetSize(cell_parent->data_dict_keys); cellid++) {
            JsonNode *here = cell_parent->data_dict.at(cell_parent->data_dict_keys[cellid]);
            json_import_cell(ctx, modname, netids, here, cell_parent->data_dict_keys[cellid]);
        }
    }

    if (ports_parent != nullptr) {
        // N.B. ports must be imported after cells for tristate behaviour
        // to be correct
        // Loop through all ports, first non-tristate then tristate to handle
        // interconnected ports correctly
        for (int portid = 0; portid < GetSize(ports_parent->data_dict_keys); portid++) {
            JsonNode *here;

            here = ports_parent->data_dict.at(ports_parent->data_dict_keys[portid]);
            JsonNode *dir_node = here->data_dict.at("direction");
            NPNR_ASSERT(dir_node->type == 'S');
            if (dir_node->data_string == "inout")
                continue;
            json_import_toplevel_port(ctx, modname, netids, ports_parent->data_dict_keys[portid], here);
        }
        for (int portid = 0; portid < GetSize(ports_parent->data_dict_keys); portid++) {
            JsonNode *here;

            here = ports_parent->data_dict.at(ports_parent->data_dict_keys[portid]);
            JsonNode *dir_node = here->data_dict.at("direction");
            NPNR_ASSERT(dir_node->type == 'S');
            if (dir_node->data_string != "inout")
                continue;
            json_import_toplevel_port(ctx, modname, netids, ports_parent->data_dict_keys[portid], here);
        }
    }
    if (node->data_dict.count("netnames")) {
        JsonNode *net_parent = node->data_dict.at("netnames");
        for (int nnid = 0; nnid < GetSize(net_parent->data_dict_keys); nnid++) {
            JsonNode *here;

            here = net_parent->data_dict.at(net_parent->data_dict_keys[nnid]);
            std::string basename = net_parent->data_dict_keys[nnid];
            if (here->data_dict.count("bits")) {
                JsonNode *bits = here->data_dict.at("bits");
                assert(bits->type == 'A');
                size_t num_bits = bits->data_array.size();
                for (size_t i = 0; i < num_bits; i++) {
                    std::string name =
                            basename + (num_bits == 1 ? "" : std::string("[") + std::to_string(i) + std::string("]"));
                    IdString net_id = ctx->id(name);
                    if (here->data_dict.count("attributes") && ctx->nets.find(net_id) != ctx->nets.end()) {
                        NetInfo *this_net = ctx->nets[net_id].get();

                        JsonNode *attr_node = here->data_dict.at("attributes");
                        if (attr_node->type != 'D')
                            log_error("JSON attribute list of \'%s\' is not a data dictionary\n",
                                      this_net->name.c_str(ctx));

                        //
                        // Loop through all attributes, adding them into the
                        // design to annotate the cell
                        //
                        for (int attrid = 0; attrid < GetSize(attr_node->data_dict_keys); attrid++) {
                            json_import_net_attrib(ctx, modname, this_net, attr_node, &this_net->attrs, attrid);
                        }
                    }
                }
            }
        }
    }
    // Import net aliases
    for (size_t i = 0; i < netids.size(); i++) {
        IdString netname = netids.at(i);
        if (!ctx->nets.count(netname))
            continue;
        for (auto &label : netlabels.at(i)) {
            IdString labelid = ctx->id(label);
            NPNR_ASSERT(!ctx->net_aliases.count(labelid));
            ctx->net_aliases[labelid] = netname;
        }
    }
    check_all_nets_driven(ctx);
    ctx->settings[ctx->id("synth")] = 1;
}
}; // End Namespace JsonParser

bool parse_json_file(std::istream &f, std::string &filename, Context *ctx)
{
    try {
        using namespace JsonParser;

        if (!f)
            log_error("failed to open JSON file.\n");

        int lineno = 1;

        JsonNode root(f, lineno);

        if (root.type != 'D')
            log_error("JSON root node is not a dictionary.\n");

        if (root.data_dict.count("modules") != 0) {
            JsonNode *modules = root.data_dict.at("modules");

            if (modules->type != 'D')
                log_error("JSON modules node is not a dictionary.\n");

            for (auto &it : modules->data_dict)
                json_import(ctx, it.first, it.second);
        }

        log_info("Checksum: 0x%08x\n", ctx->checksum());
        log_break();
        ctx->attributesToArchInfo();
        return true;
    } catch (log_execution_error_exception) {
        return false;
    }
}

bool load_json_settings(std::istream &f, std::string &filename, std::unordered_map<std::string, Property> &values)
{
    try {
        using namespace JsonParser;

        if (!f)
            log_error("failed to open JSON file.\n");

        int lineno = 1;

        JsonNode root(f, lineno);

        if (root.type != 'D')
            log_error("JSON root node is not a dictionary.\n");

        if (root.data_dict.count("modules") != 0) {
            JsonNode *modules = root.data_dict.at("modules");

            if (modules->type != 'D')
                log_error("JSON modules node is not a dictionary.\n");

            for (auto &it : modules->data_dict) {
                JsonNode *node = it.second;
                if (is_blackbox(node))
                    continue;

                if (node->data_dict.count("settings")) {
                    JsonNode *attr_node = node->data_dict.at("settings");
                    for (int attrid = 0; attrid < GetSize(attr_node->data_dict_keys); attrid++) {
                        JsonNode *param = attr_node->data_dict.at(attr_node->data_dict_keys[attrid]);
                        std::string pId = attr_node->data_dict_keys[attrid];
                        values[pId] = json_parse_attr_param_value(param);
                    }
                }
            }
        }

        return true;
    } catch (log_execution_error_exception) {
        return false;
    }
}

NEXTPNR_NAMESPACE_END
