#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020  The SymbiFlow Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier:	ISC

"""
This is intended to provide a range of helper functions around the output of
Yosys' `write_json`. Depending on the tasks, this may need to be flattened
and/or in AIG format. In any case, at minimum `proc` and usually `prep` should
be used before outputting the JSON.
"""

import json
import pprint
import re


class YosysModule:
    def __init__(self, name, module_data):
        self.name = name
        self.data = module_data

    def __str__(self):
        return "YosysModule({},\n{})".format(
            self.name, pprint.pformat(self.data)
        )

    @property
    def ports(self):
        """List of ports on a module.

        Returns a list of tuples:
        -------
        name : str
        width : int
            The width in bits
        dir : str
            The direction, should be either `input` or `output`
        """
        plist = []
        for port, pdata in sorted(self.data["ports"].items()):
            plist.append(
                (port, len(pdata["bits"]), pdata["bits"], pdata["direction"])
            )
        return plist

    @property
    def cells(self):
        """List of cells of a module, excluding Yosys-internal cells
        beginning with $.

        Returns a list of tuples:
        -------
        name : str
        type : str
        """
        clist = []
        for cell, cdata in sorted(self.data["cells"].items()):
            if cdata["type"].startswith('$'):
                continue
            clist.append((cell, cdata["type"]))
        return clist

    @property
    def all_cells(self):
        """List of cells of a module, including Yosis-internal cells

        Returns a list of tuples:
        -------
        name : str
        type : str
        """
        clist = []
        for cell, cdata in sorted(self.data["cells"].items()):
            clist.append((cell, cdata["type"]))
        return clist

    @property
    def net_names(self):
        """List the net names avilable in the design."""
        return self.data["netnames"].keys()

    @property
    def nets(self):
        """List the net ids available in the design."""
        return list(
            sorted(set(n['bits'][0] for n in self.data["netnames"].values()))
        )

    def cell_type(self, cell):
        """Return the type of a given cell"""
        for cname, cdata in self.data["cells"].items():
            if cname == cell:
                return cdata["type"]
        return None

    @property
    def module_attrs(self):
        """All attributes of a module as a dictionary"""
        return self.data["attributes"]

    def attr(self, attr, defval=None):
        """Get an attribute, or defval is not set"""
        if attr in self.module_attrs:
            return self.module_attrs[attr]
        else:
            return defval

    def __getattr__(self, attr):
        return self.attr(attr)

    def has_attr(self, attr):
        """Return true if an attribute exists"""
        return attr in self.module_attrs

    def cell_attrs(self, cell):
        """All attributes of a given cell as a dictionary"""
        return self.data["cells"][cell]["attributes"]

    def cell_attr(self, cell, attr, defval=None):
        """Get an attribute of a given cell, or defval is not set"""
        if attr in self.cell_attrs(cell):
            return self.cell_attrs(cell)[attr]
        else:
            return defval

    def net_attrs(self, netname):
        """Get all attributes of a given net as a dictionary"""
        return self.data["netnames"][netname]["attributes"]

    def net_attr(self, netname, attr, defval=None):
        """Get an attribute of a given net (specified by name),
        or defval is not set"""
        if attr in self.net_attrs(netname):
            return self.net_attrs(netname)[attr]
        else:
            return defval

    PORT_REGEX = re.compile('(.*)(\\[([0-9]+)\\])')

    def port_attrs(self, port_pin):
        """Gets all the attributes for for given pin

        Returns attributes dictionary:
        -------

        port_pin: str
        """
        m = self.PORT_REGEX.match(port_pin)
        if not m:
            return self.net_attrs(port_pin)
        port_name, _, port_idx = m.groups()
        return self.net_attrs(port_name)

    # TODO: the below code is kind of ugly, but because module and cell IO
    # specifications are inconsistent in how they are represented in the JSON,
    # it's hard to make any nicer...

    def port_conns(self, port):
        """The connections of a port

        Returns a list of connections:
        -------
        net : int
        """
        for pname, pdata in sorted(self.data["ports"].items()):
            if pname == port:
                return pdata["bits"]

    def cell_conns(self, cell, direction="input"):
        """The connections of a cell in a given direction as a 2-tuple

        Returns a list of tuples:
        -------
        port : str
        net : int
        """
        cdata = self.data["cells"][cell]
        conns = []
        for port, condata in sorted(cdata["connections"].items()):
            if cdata["port_directions"][port] == direction:
                N = len(condata)
                if N == 1:
                    conns.append((port, condata[0]))
                else:
                    for i in range(N):
                        conns.append(("{}[{}]".format(port, i), condata[i]))
        return conns

    def cell_conn_list(self, cell, port):
        """The connections of a cell in a given port as a list

        Returns a list of connections:
        -------
        net : list

        """
        data = self.data["cells"][cell]

        conns = []

        for cport, condata in sorted(data["connections"].items()):
            if cport == port:
                conns = condata

        return conns

    def cell_clk_conn(self, cell):
        """The clock net related to a given cell

        If exists returns the clock net

        net : list
        """
        data = self.data["cells"][cell]

        if "CLK" in data["connections"].keys():
            return data["connections"]["CLK"]
        else:
            return None

    def conn_io(self, net, iodir):
        """Returns a list of top level IO matching a direction and connected net number

        Returns a list:
        -------
        port : str
        """
        conn_io = []
        for port, pdata in sorted(self.data["ports"].items()):
            if pdata["direction"] == iodir:
                if net in pdata["bits"]:
                    if len(pdata["bits"]) == 1:
                        conn_io.append(port)
                    else:
                        conn_io.append(
                            "{}[{}]".format(port, pdata["bits"].index(net))
                        )
        return conn_io

    def conn_ports(self, net, pdir):
        """Returns any cell ports matching a direction and connected net number

        Returns a list of tuples:
        -------
        cell : str
        port : str
        """
        conn_ports = []
        for cell in sorted(self.data["cells"].keys()):
            cdata = self.data["cells"][cell]
            for port, condata in sorted(cdata["connections"].items()):
                if cdata["port_directions"][port] == pdir:
                    if net in condata:
                        if len(condata) == 1:
                            conn_ports.append((cell, port))
                        else:
                            conn_ports.append(
                                (
                                    cell,
                                    "{}[{}]".format(port, condata.index(net))
                                )
                            )
        return conn_ports

    def net_name(self, netid):
        """Get a net name from a given netid. "netid" is a design net unique id
        number.

        Returns string:
        -------
        netid : int
        """
        import sys
        print("Netid", netid, file=sys.stderr)
        names = []
        for n, props in self.data["netnames"].items():
            if netid in props['bits']:
                names.append(n)
        # FIXME: This fails when there are two wires with different names
        # connected to the same netid (yes, that's possible). Which name
        # should be returned in that case ?
        if len(names) != 1:
            raise KeyError("Net id {} not found".format(netid))
        return names[0]

    def net_attrs_by_netid(self, netid):
        """
        Returns attributes of a given netid. Raises RuntimeError if the same
        attribute is defined for two or more wires belonging to the same net.
        The attribute 'src' is an exception, 'src' strings are concatenated
        when defined for more than one wire.

        Returns dict:
        -------
        netid : int
        """

        attributes = {}

        for name, data in self.data["netnames"].items():
            if netid in data['bits']:

                # Join attributes
                for attr, value in data['attributes'].items():

                    # Allow multiple definitions of the same attribute only
                    # for the 'src'. Otherwise raise an exception
                    if attr in attributes and attr != 'src':
                        raise RuntimeError(
                            "Conflicting attributes '{}' on netid {}".format(
                                attr, netid))

                    # Join 'src' attribute strings
                    if attr in attributes and attr == 'src':
                        attributes[attr] += ";{}".format(value)
                    # Store the value
                    else:
                        attributes[attr] = value

        return attributes

    def net_drivers(self, net):
        """Returns a list of drivers of a given net, both top level inputs.
        and cell outputs. "cell" is set to the name of the module for top level
        IO.

        Returns a list of tuples:
        -------
        cell : str
        port : str
        """
        # top level *inputs* and cell outputs are both drivers
        io_drivers = [(self.name, _) for _ in self.conn_io(net, "input")]
        cell_drivers = self.conn_ports(net, "output")
        return io_drivers + cell_drivers

    def net_sinks(self, net):
        """Returns a list of sinks of a given net, both top level outputs.
        and cell inputs. "cell" is set to the name of the module for top level
        IO.

        Returns a list of tuples:
        -------
        cell : str
        port : str
        """
        # top level *outputs* and cell inputs are both drivers
        io_drivers = [(self.name, _) for _ in self.conn_io(net, "output")]
        cell_drivers = self.conn_ports(net, "input")
        return io_drivers + cell_drivers


class YosysJSON:
    def __init__(self, j, top=None):
        """Takes either the filename to a JSON file, or already parsed JSON
        data as a dictionary. Optionally the top level module can be specified
        too."""
        if (isinstance(j, str)):
            with open(j, 'r') as f:
                self.data = json.load(f)
        else:
            self.data = j
        if top is None:
            if len(self.data["modules"]) == 1:
                self.top = list(self.data["modules"].keys())[0]
            else:
                self.top = None
        else:
            self.top = top

    def module(self, module):
        """Get a given module (by name) as a `YosysModule`"""
        if module not in self.data["modules"]:
            raise KeyError(
                "No yosys module named {} (only have {})".format(
                    module, self.data["modules"].keys()
                )
            )
        return YosysModule(module, self.data["modules"][module])

    def modules_with_attr(self, attr_name, attr_value):
        """Return a list of `YosysModule`s, selecting based on
        a given attribute"""
        mods = []
        for mod in self.data["modules"]:
            ymod = self.module(mod)
            if ymod.has_attr(attr_name) and ymod.attr(attr_name) == attr_value:
                mods.append(ymod)
        return mods

    def all_modules(self):
        """Return a list of the names of all modules in the design,
        sorted alphabetically"""
        return sorted(self.data["modules"].keys())

    @property
    def top_module(self):
        """Get a given module (by name) as a `YosysModule`"""
        return self.module(self.top)

    def has_module(self, module):
        """Return true if a module exists"""
        return module in self.data["modules"]

    def get_module_file(self, module):
        """Return the filename in which a given module lives"""
        src = self.module(module).attr("src")
        cpos = src.rfind(":")
        return src[0:cpos]
