import re
from collections import namedtuple, defaultdict

from data_structs import PinDirection

Element = namedtuple('Element', 'loc type name ios')
Wire = namedtuple('Wire', 'srcloc name inverted')
VerilogIO = namedtuple('VerilogIO', 'name direction ioloc')


def loc2str(loc):
    return "X" + str(loc.x) + "Y" + str(loc.y)


class VModule(object):
    '''Represents a Verilog module for QLAL4S3B FASM'''

    def __init__(
            self,
            vpr_tile_grid,
            vpr_tile_types,
            cells_library,
            pcf_data,
            belinversions,
            interfaces,
            designconnections,
            org_loc_map,
            cand_map,
            inversionpins,
            io_to_fbio,
            useinversionpins=True
    ):
        '''Prepares initial structures.

        Refer to fasm2bels.py for input description.
        '''

        self.vpr_tile_grid = vpr_tile_grid
        self.vpr_tile_types = vpr_tile_types
        self.cells_library = cells_library
        self.pcf_data = pcf_data
        self.belinversions = belinversions
        self.interfaces = interfaces
        self.designconnections = designconnections
        self.org_loc_map = org_loc_map
        self.cand_map = cand_map
        self.inversionpins = inversionpins
        self.useinversionpins = useinversionpins
        self.io_to_fbio = io_to_fbio

        # dictionary holding inputs, outputs
        self.ios = {}
        # dictionary holding declared wires (wire value;)
        self.wires = {}
        # dictionary holding Verilog elements
        self.elements = defaultdict(dict)
        # dictionary holding assigns (assign key = value;)
        self.assigns = {}

        # helper representing last input id
        self.last_input_id = 0
        # helper representing last output id
        self.last_output_id = 0

        self.qlal4s3bmapping = {
            'LOGIC': 'logic_cell_macro',
            'ASSP': 'qlal4s3b_cell_macro',
            'BIDIR': 'gpio_cell_macro',
            'RAM': 'ram8k_2x1_cell_macro',
            'MULT': 'qlal4s3_mult_cell_macro',
            'GMUX': 'gclkbuff',
            'QMUX': 'qhsckbuff',
            'CLOCK': 'ckpad',
            'inv': 'inv'
        }

        self.qlal4s3_pinmap = {
            "ckpad": {
                "IP": "P",
                "IC": "Q",
            },
            "gclkbuff": {
                "IC": "A",
                "IZ": "Z",
            },
            "qhsckbuff": {
                "HSCKIN": "A",
                "IZ": "Z"
            },
        }

    def group_vector_signals(self, signals, io=False):

        # IOs beside name, have also direction, convert them to format
        # we can process
        if io:
            orig_ios = signals
            ios = dict()
            for s in signals:
                id = Wire(s.name, 'io', False)
                ios[id] = s.name
            signals = ios

        vectors = dict()
        new_signals = dict()

        array = re.compile(
            r'(?P<varname>[a-zA-Z_][a-zA-Z_0-9$]+)\[(?P<arrindex>[0-9]+)\]'
        )

        # first find the vectors
        for signalid in signals:
            match = array.match(signals[signalid])
            if match:
                varname = match.group('varname')
                arrayindex = int(match.group('arrindex'))

                if varname not in vectors:
                    vectors[varname] = dict()
                    vectors[varname]['max'] = 0
                    vectors[varname]['min'] = 0

                if arrayindex > vectors[varname]['max']:
                    vectors[varname]['max'] = arrayindex

                if arrayindex < vectors[varname]['min']:
                    vectors[varname]['min'] = arrayindex

            # if signal is not a part of a vector leave it
            else:
                new_signals[signalid] = signals[signalid]

        # add vectors to signals dict
        for vec in vectors:
            name = '[{max}:{min}] {name}'.format(
                max=vectors[vec]['max'], min=vectors[vec]['min'], name=vec
            )
            id = Wire(name, 'vector', False)
            new_signals[id] = name

        if io:
            # we need to restore the direction info
            new_ios = list()
            for s in new_signals:
                signalname = new_signals[s].split()
                signalname = signalname[-1]
                io = [
                    x.direction
                    for x in orig_ios
                    if x.name.startswith(signalname)
                ]
                direction = io[0]
                new_ios.append((direction, new_signals[s]))
            return new_ios
        else:
            return new_signals

    def group_array_values(self, parameters: dict):
        '''Groups pin names that represent array indices.

        Parameters
        ----------
        parameters: dict
            A dictionary holding original parameters

        Returns
        -------
        dict: parameters with grouped array indices
        '''
        newparameters = dict()
        arraydst = re.compile(
            r'(?P<varname>[a-zA-Z_][a-zA-Z_0-9$]+)\[(?P<arrindex>[0-9]+)\]'
        )
        for dst, src in parameters.items():
            match = arraydst.match(dst)
            if match:
                varname = match.group('varname')
                arrindex = int(match.group('arrindex'))
                if varname not in newparameters:
                    newparameters[varname] = {arrindex: src}
                else:
                    newparameters[varname][arrindex] = src
            else:
                newparameters[dst] = src
        return newparameters

    def form_simple_assign(self, loc, parameters):
        ioname = self.get_io_name(loc)

        assign = ""
        direction = self.get_io_config(parameters)

        if direction == 'input':
            assign = "    assign {} = {};".format(parameters["IZ"], ioname)
        elif direction == 'output':
            assign = "    assign {} = {};".format(ioname, parameters["OQI"])
        elif direction is None:
            pass
        else:
            assert False, "Unknown IO configuration"

        return assign

    def form_verilog_element(self, loc, typ: str, name: str, parameters: dict):
        '''Creates an entry representing single Verilog submodule.

        Parameters
        ----------
        loc: Loc
            Cell coordinates
        typ: str
            Cell type
        name: str
            Name of the submodule
        parameters: dict
            Map from input pin to source wire

        Returns
        -------
        str: Verilog entry
        '''
        if typ == 'BIDIR':

            # We do not emit the BIDIR cell for non inout IOs
            direction = self.get_io_config(parameters)
            if direction is None:
                return ""
            elif direction != 'inout':
                return self.form_simple_assign(loc, parameters)

        params = []
        moduletype = self.qlal4s3bmapping[typ]
        pin_map = self.qlal4s3_pinmap.get(moduletype, dict())
        result = f'    {moduletype} {name} ('
        fixedparameters = self.group_array_values(parameters)
        # get inputs, strip vector's pin indexes
        input_pins = [
            pin.name.split('[')[0]
            for pin in self.cells_library[typ].pins
            if pin.direction == PinDirection.INPUT
        ]
        dummy_wires = []

        for inpname, inp in fixedparameters.items():
            mapped_inpname = pin_map.get(inpname, inpname)
            if isinstance(inp, dict):
                arr = []
                dummy_wire = f'{moduletype}_{name}_{inpname}'
                max_dummy_index = 0
                need_dummy = False
                maxindex = max([val for val in inp.keys()])
                for i in reversed(range(maxindex + 1)):
                    if i not in inp:
                        # do not assign constants to outputs
                        if inpname in input_pins:
                            arr.append("1'b0")
                        else:
                            if i > max_dummy_index:
                                max_dummy_index = i
                            arr.append("{}[{}]".format(dummy_wire, i))
                            need_dummy = True
                    else:
                        arr.append(inp[i])
                arrlist = ', '.join(arr)
                params.append(f'.{mapped_inpname}({{{arrlist}}})')
                if need_dummy:
                    dummy_wires.append(
                        f'    wire [{max_dummy_index}:0] {dummy_wire};'
                    )
            else:
                params.append(f'.{mapped_inpname}({inp})')
        if self.useinversionpins:
            if typ in self.inversionpins:
                for toinvert, inversionpin in self.inversionpins[typ].items():
                    if toinvert in self.belinversions[loc][typ]:
                        params.append(f".{inversionpin}(1'b1)")
                    else:
                        params.append(f".{inversionpin}(1'b0)")

        # handle BIDIRs and CLOCKs
        if typ in ['CLOCK', 'BIDIR']:
            ioname = self.get_io_name(loc)

            moduletype = self.qlal4s3bmapping[typ]
            pin_map = self.qlal4s3_pinmap.get(moduletype, dict())

            params.append(".{}({})".format(pin_map.get("IP", "IP"), ioname))

        result += f',\n{" " * len(result)}'.join(sorted(params)) + ');\n'
        wires = ''
        for wire in dummy_wires:
            wires += f'\n{wire}'
        result = wires + '\n\n' + result
        return result

    @staticmethod
    def get_element_name(type, loc):
        '''Forms element name from its type and FASM feature name.'''
        return f'{type}_X{loc.x}_Y{loc.y}'

    @staticmethod
    def get_element_type(type):
        match = re.match(r"(?P<type>[A-Za-z]+)(?P<index>[0-9]+)?", type)
        assert match is not None, type
        return match.group("type")

    def get_bel_type_and_connections(self, loc, connections, direction):
        '''For a given connection list returns a dictionary
        with bel types and connections to them
        '''

        cells = self.vpr_tile_grid[loc].cells

        if type(connections) == str:
            inputnames = [connections]
            # convert connections to dict
            connections = dict()
            connections[inputnames[0]] = inputnames[0]
        else:
            inputnames = [name for name in connections.keys()]

        # Some switchbox inputs are named like "<cell><cell_index>_<pin>"
        # Make a list of them for compatison in the following step.
        cell_input_names = defaultdict(lambda: [])
        for name in inputnames:
            fields = name.split("_", maxsplit=1)
            if len(fields) == 2:
                cell, pin = fields
                cell_input_names[cell].append(pin)

        used_cells = []
        for cell in cells:
            cell_name = "{}{}".format(cell.type, cell.index)

            cellpins = [
                pin.name
                for pin in self.cells_library[cell.type].pins
                if pin.direction == direction
            ]

            # check every connection pin if it has
            for pin in cellpins:

                # Cell name and pin name match
                if cell_name in cell_input_names:
                    if pin in cell_input_names[cell_name]:
                        used_cells.append(cell)
                        break

                # The pin name matches exactly the specified input name
                if pin in inputnames:
                    used_cells.append(cell)
                    break

        # assing connection to a cell
        cell_connections = {}
        for cell in used_cells:
            cell_name = "{}{}".format(cell.type, cell.index)

            cell_connections[cell_name] = dict()
            cellpins = [
                pin.name
                for pin in self.cells_library[cell.type].pins
                if pin.direction == direction
            ]

            for key in connections.keys():
                if key in cellpins:
                    cell_connections[cell_name][key] = connections[key]

                # Some switchbox inputs are named like
                # "<cell><cell_index>_<pin>". Break down the name and check.
                fields = key.split("_", maxsplit=1)
                if len(fields) == 2:
                    key_cell, key_pin = fields
                    if key_cell == cell_name and key_pin in cellpins:
                        cell_connections[cell_name][key_pin] = connections[key]

        return cell_connections

    def new_io_name(self, direction):
        '''Creates a new IO name for a given direction.

        Parameters
        ----------
        direction: str
            Direction of the IO, can be 'input' or 'output'
        '''
        # TODO add support for inout
        assert direction in ['input', 'output', 'inout']
        if direction == 'output':
            name = f'out_{self.last_output_id}'
            self.last_output_id += 1
        elif direction == 'input':
            name = f'in_{self.last_input_id}'
            self.last_input_id += 1
        else:
            pass
        return name

    def get_wire(self, loc, wire, inputname):
        '''Creates or gets an existing wire for a given source.

        Parameters
        ----------
        loc: Loc
            Location of the destination cell
        wire: tuple
            A tuple of location of the source cell and source pin name
        inputname: str
            A name of the destination pin

        Returns
        -------
        str: wire name
        '''
        isoutput = self.vpr_tile_grid[loc].type == 'SYN_IO'
        if isoutput:
            # outputs are never inverted
            inverted = False
        else:
            # determine if inverted
            inverted = (
                inputname in self.belinversions[loc][
                    self.vpr_tile_grid[loc].type]
            )
        wireid = Wire(wire[0], wire[1], inverted)
        if wireid in self.wires:
            # if wire already exists, use it
            return self.wires[wireid]

        # first create uninverted wire
        uninvertedwireid = Wire(wire[0], wire[1], False)
        if uninvertedwireid in self.wires:
            # if wire already exists, use it
            wirename = self.wires[uninvertedwireid]
        else:
            srcname = self.vpr_tile_grid[wire[0]].name
            type_connections = self.get_bel_type_and_connections(
                wire[0], wire[1], PinDirection.OUTPUT
            )
            # there should be only one type here
            srctype = [type for type in type_connections.keys()][0]
            srconame = wire[1]
            if srctype == 'SYN_IO':
                # if source is input, use its name
                if wire[0] not in self.ios:
                    self.ios[wire[0]] = VerilogIO(
                        name=self.new_io_name('input'),
                        direction='input',
                        ioloc=wire[0]
                    )
                assert self.ios[wire[0]].direction == 'input'
                wirename = self.ios[wire[0]].name
            else:
                # form a new wire name
                wirename = f'{srcname}_{srconame}'
            if srctype not in self.elements[wire[0]]:
                # if the source element does not exist, create it
                self.elements[wire[0]][srctype] = Element(
                    wire[0], self.get_element_type(srctype),
                    self.get_element_name(srctype, wire[0]),
                    {srconame: wirename}
                )
            else:
                # add wirename to the existing element
                self.elements[wire[0]][srctype].ios[srconame] = wirename
            if not isoutput and srctype != 'SYN_IO':
                # add wire
                self.wires[uninvertedwireid] = wirename
            elif isoutput:
                # add assign to output
                self.assigns[self.ios[loc].name] = wirename

        if not inverted or (
                self.useinversionpins and
                inputname in self.inversionpins[self.vpr_tile_grid[loc].type]):
            # if not inverted or we're not inverting, just finish
            return wirename

        # else create an inverted and wire for it
        invertername = f'{wirename}_inverter'

        invwirename = f'{wirename}_inv'

        inverterios = {'Q': invwirename, 'A': wirename}

        inverterelement = Element(wire[0], 'inv', invertername, inverterios)
        self.elements[wire[0]]['inv'] = inverterelement
        invertedwireid = Wire(wire[0], wire[1], True)
        self.wires[invertedwireid] = invwirename
        return invwirename

    def parse_bels(self):
        '''Converts BELs to Verilog-like structures.'''
        # TODO add support for direct input-to-output
        # first parse outputs to create wires for them

        # parse outputs first to properly handle namings
        for currloc, connections in self.designconnections.items():
            type_connections = self.get_bel_type_and_connections(
                currloc, connections, PinDirection.OUTPUT
            )

            for currtype, connections in type_connections.items():
                currname = self.get_element_name(currtype, currloc)
                outputs = {}

                # Check each output
                for output_name, (
                        loc,
                        wire,
                ) in connections.items():

                    # That wire is connected to something. Skip processing
                    # of the cell here
                    if loc is not None:
                        continue

                    # Connect the global wire
                    outputs[output_name] = wire

                # No outputs connected, don't add.
                if not len(outputs):
                    continue

                # If Element does not exist, create it
                if currtype not in self.elements[currloc]:
                    self.elements[currloc][currtype] = Element(
                        currloc, self.get_element_type(currtype), currname,
                        outputs
                    )
                # Else update IOs
                else:
                    self.elements[currloc][currtype].ios.update(outputs)

        # process of BELs
        for currloc, connections in self.designconnections.items():
            # Extract type and form name for the BEL
            # Current location may be a multi cell location.
            # Split the connection list into a to a set of connections
            # for each used cell type
            type_connections = self.get_bel_type_and_connections(
                currloc, connections, PinDirection.INPUT
            )

            for currtype in type_connections:
                currname = self.get_element_name(currtype, currloc)
                connections = type_connections[currtype]
                inputs = {}
                # form all inputs for the BEL
                for inputname, wire in connections.items():
                    if wire[1] == 'VCC':
                        inputs[inputname] = "1'b1"
                        continue
                    elif wire[1] == 'GND':
                        inputs[inputname] = "1'b0"
                        continue
                    elif wire[1].startswith("CAND"):
                        dst = (currloc, inputname)
                        dst = self.org_loc_map.get(dst, dst)
                        if dst[0] in self.cand_map:
                            inputs[inputname] = self.cand_map[dst[0]][wire[1]]
                        continue
                    srctype = self.vpr_tile_grid[wire[0]].type
                    srctype_cells = self.vpr_tile_types[srctype].cells
                    if len(set(srctype_cells).intersection(set(
                        ['BIDIR', 'LOGIC', 'ASSP', 'RAM', 'MULT']))) > 0:
                        # FIXME handle already inverted pins
                        # TODO handle inouts
                        wirename = self.get_wire(currloc, wire, inputname)
                        inputs[inputname] = wirename
                    else:
                        raise Exception(
                            'Not supported cell type {}'.format(srctype)
                        )
                if currtype not in self.elements[currloc]:
                    # If Element does not exist, create it
                    self.elements[currloc][currtype] = Element(
                        currloc, self.get_element_type(currtype), currname,
                        inputs
                    )
                else:
                    # else update IOs
                    self.elements[currloc][currtype].ios.update(inputs)

        # Prune BELs that do not drive anythin (have all outputs disconnected)
        for loc, elements in list(self.elements.items()):
            for type, element in list(elements.items()):

                # Handle IO cells
                if element.type in ['CLOCK', 'BIDIR', 'SDIOMUX']:

                    if element.type == "CLOCK":
                        direction = "input"
                    else:
                        direction = self.get_io_config(element.ios)

                    # Remove the cell if none is connected
                    if direction is None:
                        del elements[type]

                # Handle non-io cells
                else:

                    # Get connected pin names and output pin names
                    connected_pins = set(element.ios.keys())
                    output_pins = set(
                        [
                            pin.name.split('[')[0]
                            for pin in self.cells_library[element.type].pins
                            if pin.direction == PinDirection.OUTPUT
                        ]
                    )

                    # Remove the cell if none is connected
                    if not len(connected_pins & output_pins):
                        del elements[type]

            # Prune the whole location
            if not len(elements):
                del self.elements[loc]

    def get_io_name(self, loc):

        # default pin name
        name = loc2str(loc) + '_inout'
        # check if we have the original name for this io
        if self.pcf_data is not None:
            pin = self.io_to_fbio.get(loc, None)
            if pin is not None and pin in self.pcf_data:
                name = self.pcf_data[pin]
                name = name.replace('(', '[')
                name = name.replace(')', ']')

        return name

    def get_io_config(self, ios):
        # decode direction
        # direction is configured by routing 1 or 0 to certain inputs

        if 'IE' in ios:
            output_en = ios['IE'] != "1'b0"
        else:
            # outputs is enabled by default
            output_en = True
        if 'INEN' in ios:
            input_en = ios['INEN'] != "1'b0"
        else:
            # inputs are disabled by default
            input_en = False

        if input_en and output_en:
            direction = 'inout'
        elif input_en:
            direction = 'input'
        elif output_en:
            direction = 'output'
        else:
            direction = None

        # Output unrouted. Discard
        if direction == 'input':
            if 'IZ' not in ios:
                return None

        return direction

    def generate_ios(self):
        '''Generates IOs and their wires

        Returns
        -------
        None
        '''
        for eloc, locelements in self.elements.items():
            for element in locelements.values():
                if element.type in ['CLOCK', 'BIDIR', 'SDIOMUX']:

                    if element.type == "CLOCK":
                        direction = "input"
                    else:
                        direction = self.get_io_config(element.ios)

                    # Add the input if used
                    if direction is not None:
                        name = self.get_io_name(eloc)
                        self.ios[eloc] = VerilogIO(
                            name=name, direction=direction, ioloc=eloc
                        )

    def generate_verilog(self):
        '''Creates Verilog module

        Returns
        -------
        str: A Verilog module for given BELs
        '''
        ios = ''
        wires = ''
        assigns = ''
        elements = ''

        self.generate_ios()

        if len(self.ios) > 0:
            sortedios = sorted(
                self.ios.values(), key=lambda x: (x.direction, x.name)
            )
            grouped_ios = self.group_vector_signals(sortedios, True)
            ios = '\n    '
            ios += ',\n    '.join([f'{x[0]} {x[1]}' for x in grouped_ios])

        grouped_wires = self.group_vector_signals(self.wires)
        if len(grouped_wires) > 0:
            wires += '\n'
            for wire in grouped_wires.values():
                wires += f'    wire {wire};\n'

        if len(self.assigns) > 0:
            assigns += '\n'
            for dst, src in self.assigns.items():
                assigns += f'    assign {dst} = {src};\n'

        if len(self.elements) > 0:
            for eloc, locelements in self.elements.items():
                for element in locelements.values():
                    if element.type != 'SYN_IO':
                        elements += '\n'
                        elements += self.form_verilog_element(
                            eloc, element.type, element.name, element.ios
                        )

        verilog = (
            f'module top ({ios});\n'
            f'{wires}'
            f'{assigns}'
            f'{elements}'
            f'\n'
            f'endmodule'
        )
        return verilog

    def generate_pcf(self):
        pcf = ''
        for io in self.ios.values():
            if io.ioloc in self.io_to_fbio:
                pcf += f'set_io {io.name} {self.io_to_fbio[io.ioloc]}\n'
        return pcf

    def generate_qcf(self):
        qcf = '#[Fixed Pin Placement]\n'
        for io in self.ios.values():
            if io.ioloc in self.io_to_fbio:
                qcf += f'place {io.name} {self.io_to_fbio[io.ioloc]}\n'
        return qcf
