/*
 *  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;
    }
};

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]);
    if (param->type == 'N') {
        (*dest)[pId].setNumber(param->data_number);
    } else if (param->type == 'S')
        (*dest)[pId].setString(param->data_string);
    else
        log_error("JSON parameter type of \"%s\' of cell \'%s\' not supported\n", pId.c_str(ctx),
                  cell->name.c_str(ctx));

    if (json_debug)
        log_info("    Added parameter \'%s\'=%s to cell \'%s\' "
                 "of module \'%s\'\n",
                 pId.c_str(ctx), cell->params[pId].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]);
    if (param->type == 'N') {
        (*dest)[pId].setNumber(param->data_number);
    } else if (param->type == 'S')
        (*dest)[pId].setString(param->data_string);
    else
        log_error("JSON parameter type of \"%s\' of net \'%s\' not supported\n", pId.c_str(ctx), net->name.c_str(ctx));
    if (json_debug)
        log_info("    Added parameter \'%s\'=%s to net \'%s\' "
                 "of module \'%s\'\n",
                 pId.c_str(ctx), net->attrs[pId].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]);
    if (param->type == 'N') {
        (*dest)[pId].setNumber(param->data_number);
    } else if (param->type == 'S')
        (*dest)[pId].setString(param->data_string);
    else
        log_error("JSON parameter type of \"%s\' of module not supported\n", pId.c_str(ctx));
    if (json_debug)
        log_info("    Added parameter \'%s\'=%s module \'%s\'\n", pId.c_str(ctx), (*dest)[pId].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 = net->name;
    pinfo.net = net;
    pinfo.type = type;
    ctx->ports[net->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::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("]"));
                    if (prefer_netlabel(name, netlabels.at(netid)))
                        netlabels.at(netid) = name;
                }
            }
        }
    }
    std::vector<IdString> netids;
    std::transform(netlabels.begin(), netlabels.end(), std::back_inserter(netids),
                   [ctx](const std::string &s) { return ctx->id(s); });
    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);
                        }
                    }
                }
            }
        }
    }
    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];
                        if (param->type == 'N') {
                            values[pId].setNumber(param->data_number);
                        } else if (param->type == 'S')
                            values[pId].setString(param->data_string);
                        else
                            log_error("JSON parameter type of \"%s\' of module not supported\n", pId.c_str());
                    }
                }
            }
        }

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

NEXTPNR_NAMESPACE_END
