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):
        bloc = loc2str(loc)
        ioname = self.get_io_name(loc)

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

        print(direction, bloc, ioname, 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[loc]
            if 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():
            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():
            qcf += f'place {io.name} {self.io_to_fbio[io.ioloc]}\n'
        return qcf
