#!/usr/bin/env python3
"""
This utility generates a FASM file with a default bitstream configuration for
the given device.
"""
import argparse
import colorsys
from enum import Enum

import lxml.etree as ET

from data_structs import PinDirection, SwitchboxPinType
from data_import import import_data

from utils import yield_muxes

from switchbox_model import SwitchboxModel

# =============================================================================
duplicate = {}


class SwitchboxConfigBuilder:
    """
    This class is responsible for routing a switchbox according to the
    requested parameters and writing FASM features that configure it.
    """

    class NodeType(Enum):
        MUX = 0
        SOURCE = 1
        SINK = 2

    class Node:
        """
        Represents a graph node that corresponds either to a switchbox mux
        output or to a virtual source / sink node.
        """

        def __init__(self, type, key):
            self.type = type
            self.key = key

            # Current "net"
            self.net = None

            # Mux input ids indexed by keys and mux selection
            self.inp = {}
            self.sel = None

            # Mux inputs driven by this node as keys
            self.out = set()

    def __init__(self, switchbox):
        self.switchbox = switchbox
        self.nodes = {}

        # Build nodes representing the switchbox connectivity graph
        self._build_nodes()

    def _build_nodes(self):
        """
        Creates all nodes for routing.
        """

        # Create all mux nodes
        for stage, switch, mux in yield_muxes(self.switchbox):

            # Create the node
            key = (stage.id, switch.id, mux.id)
            node = self.Node(self.NodeType.MUX, key)

            # Store the node
            if stage.type not in self.nodes:
                self.nodes[stage.type] = {}

            assert node.key not in self.nodes[stage.type
                                              ], (stage.type, node.key)
            self.nodes[stage.type][node.key] = node

        # Create all source and sink nodes, populate their connections with mux
        # nodes.
        for pin in self.switchbox.pins:

            # Node type
            if pin.direction == PinDirection.INPUT:
                node_type = self.NodeType.SOURCE
            elif pin.direction == PinDirection.OUTPUT:
                node_type = self.NodeType.SINK
            else:
                assert False, node_type

            # Create one for each stage type
            stage_ids = set([loc.stage_id for loc in pin.locs])
            for stage_id in stage_ids:

                # Create the node
                key = pin.name
                node = self.Node(node_type, key)

                # Initially annotate source nodes with net names
                if node.type == self.NodeType.SOURCE:
                    node.net = pin.name

                # Get the correct node list
                stage_type = self.switchbox.stages[stage_id].type
                assert stage_type in self.nodes, stage_type
                nodes = self.nodes[stage_type]

                # Add the node
                assert node.key not in self.nodes, node.key
                nodes[node.key] = node

            # Populate connections
            for pin_loc in pin.locs:

                # Get the correct node list
                stage_type = self.switchbox.stages[pin_loc.stage_id].type
                assert stage_type in self.nodes, stage_type
                nodes = self.nodes[stage_type]

                if pin.direction == PinDirection.INPUT:

                    # Get the mux node
                    key = (pin_loc.stage_id, pin_loc.switch_id, pin_loc.mux_id)
                    assert key in nodes, key
                    node = nodes[key]

                    key = (
                        self.switchbox.type, pin_loc.stage_id,
                        pin_loc.switch_id, pin_loc.mux_id
                    )
                    if (key in duplicate  # Mux has multiple inputs selected
                            and (pin_loc.pin_id in duplicate[key]
                                 )  # Current selection is duplicate
                            and not (key[0].startswith("SB_TOP_IFC"))
                        ):  # Ignore TOP switchboxes
                        print(
                            "Warning: duplicate: {} - {}".format(
                                key, pin_loc.pin_id
                            )
                        )
                        continue

                    # Append reference to the input pin to the node
                    key = pin.name
                    assert key == "GND" or key not in node.inp, key
                    node.inp[key] = pin_loc.pin_id

                    # Get the SOURCE node
                    key = pin.name
                    assert key in nodes, key
                    node = nodes[key]

                    # Append the mux node as a sink
                    key = (pin_loc.stage_id, pin_loc.switch_id, pin_loc.mux_id)
                    node.out.add(key)

                elif pin.direction == PinDirection.OUTPUT:

                    # Get the sink node
                    key = pin.name
                    assert key in nodes, key
                    node = nodes[key]
                    assert node.type == self.NodeType.SINK

                    # Append reference to the mux
                    key = (pin_loc.stage_id, pin_loc.switch_id, pin_loc.mux_id)
                    node.inp[key] = 0

                    # Get the mux node
                    key = (pin_loc.stage_id, pin_loc.switch_id, pin_loc.mux_id)
                    assert key in nodes, key
                    node = nodes[key]

                    # Append the sink as the mux sink
                    key = pin.name
                    node.out.add(key)

                else:
                    assert False, pin.direction

        # Populate mux to mux connections
        for conn in self.switchbox.connections:

            # Get the correct node list
            stage_type = self.switchbox.stages[conn.dst.stage_id].type
            assert stage_type in self.nodes, stage_type
            nodes = self.nodes[stage_type]

            # Get the node
            key = (conn.dst.stage_id, conn.dst.switch_id, conn.dst.mux_id)
            assert key in nodes, key
            node = nodes[key]

            # Add its input and pin index
            key = (conn.src.stage_id, conn.src.switch_id, conn.src.mux_id)
            node.inp[key] = conn.dst.pin_id

            # Get the source node
            key = (conn.src.stage_id, conn.src.switch_id, conn.src.mux_id)
            assert key in nodes, key
            node = nodes[key]

            # Add the destination node to its outputs
            key = (conn.dst.stage_id, conn.dst.switch_id, conn.dst.mux_id)
            node.out.add(key)

    def stage_inputs(self, stage_type):
        """
        Yields inputs of the given stage type
        """
        assert stage_type in self.nodes, stage_type
        for node in self.nodes[stage_type].values():
            if node.type == self.NodeType.SOURCE:
                yield node.key

    def stage_outputs(self, stage_type):
        """
        Yields outputs of the given stage type
        """
        assert stage_type in self.nodes, stage_type
        for node in self.nodes[stage_type].values():
            if node.type == self.NodeType.SINK:
                yield node.key

    def propagate_input(self, stage_type, input_name):
        """
        Recursively propagates a net from an input pin to all reachable
        mux / sink nodes.
        """

        # Get the correct node list
        assert stage_type in self.nodes, stage_type
        nodes = self.nodes[stage_type]

        def walk(node):

            # Examine all driven nodes
            for sink_key in node.out:
                assert sink_key in nodes, sink_key
                sink_node = nodes[sink_key]

                # The sink is free
                if sink_node.net is None:

                    # Assign it to the net
                    sink_node.net = node.net
                    if sink_node.type == self.NodeType.MUX:
                        sink_node.sel = sink_node.inp[node.key]

                    # Expand
                    walk(sink_node)

        # Find the source node
        assert input_name in nodes, input_name
        node = nodes[input_name]

        # Walk downstream
        node.net = input_name
        walk(node)

    def ripup(self, stage_type):
        """
        Rips up all routes within the given stage
        """
        assert stage_type in self.nodes, stage_type
        for node in self.nodes[stage_type].values():
            if node.type != self.NodeType.SOURCE:
                node.net = None
                node.sel = None

    def check_nodes(self):
        """
        Check if all mux nodes have their selections set
        """
        result = True

        for stage_type, nodes in self.nodes.items():
            for key, node in nodes.items():

                if node.type == self.NodeType.MUX and node.sel is None:
                    result = False
                    print("WARNING: mux unconfigured", key)

        return result

    def fasm_features(self, loc):
        """
        Returns a list of FASM lines that correspond to the routed switchbox
        configuration.
        """
        lines = []

        for stage_type, nodes in self.nodes.items():
            for key, node in nodes.items():

                # For muxes with active selection
                if node.type == self.NodeType.MUX and node.sel is not None:
                    stage_id, switch_id, mux_id = key

                    # Get FASM features using the switchbox model.
                    features = SwitchboxModel.get_metadata_for_mux(
                        loc, self.switchbox.stages[stage_id], switch_id,
                        mux_id, node.sel
                    )
                    lines.extend(features)

        return lines

    def dump_dot(self):
        """
        Dumps a routed switchbox visualization into Graphviz format for
        debugging purposes.
        """
        dot = []

        def key2str(key):
            if isinstance(key, str):
                return key
            else:
                return "st{}_sw{}_mx{}".format(*key)

        def fixup_label(lbl):
            lbl = lbl.replace("[", "(").replace("]", ")")

        # All nets
        nets = set()
        for nodes in self.nodes.values():
            for node in nodes.values():
                if node.net is not None:
                    nets.add(node.net)

        # Net colors
        node_colors = {None: "#C0C0C0"}
        edge_colors = {None: "#000000"}

        nets = sorted(list(nets))
        for i, net in enumerate(nets):

            hue = i / len(nets)
            light = 0.33
            saturation = 1.0

            r, g, b = colorsys.hls_to_rgb(hue, light, saturation)
            color = "#{:02X}{:02X}{:02X}".format(
                int(r * 255.0),
                int(g * 255.0),
                int(b * 255.0),
            )

            node_colors[net] = color
            edge_colors[net] = color

        # Add header
        dot.append("digraph {} {{".format(self.switchbox.type))
        dot.append("  graph [nodesep=\"1.0\", ranksep=\"20\"];")
        dot.append("  splines = \"false\";")
        dot.append("  rankdir = LR;")
        dot.append("  margin = 20;")
        dot.append("  node [style=filled];")

        # Stage types
        for stage_type, nodes in self.nodes.items():

            # Stage header
            dot.append("  subgraph \"cluster_{}\" {{".format(stage_type))
            dot.append("    label=\"Stage '{}'\";".format(stage_type))

            # Nodes and internal mux edges
            for key, node in nodes.items():

                # Source node
                if node.type == self.NodeType.SOURCE:
                    name = "{}_inp_{}".format(stage_type, key2str(key))
                    label = key
                    color = node_colors[node.net]

                    dot.append(
                        "  \"{}\" [shape=octagon label=\"{}\" fillcolor=\"{}\"];"
                        .format(
                            name,
                            label,
                            color,
                        )
                    )

                # Sink node
                elif node.type == self.NodeType.SINK:
                    name = "{}_out_{}".format(stage_type, key2str(key))
                    label = key
                    color = node_colors[node.net]

                    dot.append(
                        "  \"{}\" [shape=octagon label=\"{}\" fillcolor=\"{}\"];"
                        .format(
                            name,
                            label,
                            color,
                        )
                    )

                # Mux node
                elif node.type == self.NodeType.MUX:
                    name = "{}_{}".format(stage_type, key2str(key))
                    dot.append("    subgraph \"cluster_{}\" {{".format(name))
                    dot.append(
                        "      label=\"{}, sel={}\";".format(
                            str(key), node.sel
                        )
                    )

                    # Inputs
                    for drv_key, pin in node.inp.items():
                        if node.sel == pin:
                            assert drv_key in nodes, drv_key
                            net = nodes[drv_key].net
                        else:
                            net = None

                        name = "{}_{}_{}".format(stage_type, key2str(key), pin)
                        label = pin
                        color = node_colors[net]

                        dot.append(
                            "      \"{}\" [shape=ellipse label=\"{}\" fillcolor=\"{}\"];"
                            .format(
                                name,
                                label,
                                color,
                            )
                        )

                    # Output
                    name = "{}_{}".format(stage_type, key2str(key))
                    label = "out"
                    color = node_colors[node.net]

                    dot.append(
                        "      \"{}\" [shape=ellipse label=\"{}\" fillcolor=\"{}\"];"
                        .format(
                            name,
                            label,
                            color,
                        )
                    )

                    # Internal mux edges
                    for drv_key, pin in node.inp.items():
                        if node.sel == pin:
                            assert drv_key in nodes, drv_key
                            net = nodes[drv_key].net
                        else:
                            net = None

                        src_name = "{}_{}_{}".format(
                            stage_type, key2str(key), pin
                        )
                        dst_name = "{}_{}".format(stage_type, key2str(key))
                        color = edge_colors[net]

                        dot.append(
                            "      \"{}\" -> \"{}\" [color=\"{}\"];".format(
                                src_name,
                                dst_name,
                                color,
                            )
                        )

                    dot.append("    }")

                else:
                    assert False, node.type

            # Mux to mux connections
            for key, node in nodes.items():

                # Source node
                if node.type == self.NodeType.SOURCE:
                    pass

                # Sink node
                elif node.type == self.NodeType.SINK:
                    assert len(node.inp) == 1, node.inp
                    src_key = next(iter(node.inp.keys()))

                    dst_name = "{}_out_{}".format(stage_type, key2str(key))
                    if isinstance(src_key, str):
                        src_name = "{}_inp_{}".format(
                            stage_type, key2str(src_key)
                        )
                    else:
                        src_name = "{}_{}".format(stage_type, key2str(src_key))

                    color = node_colors[node.net]

                    dot.append(
                        "    \"{}\" -> \"{}\" [color=\"{}\"];".format(
                            src_name,
                            dst_name,
                            color,
                        )
                    )

                # Mux node
                elif node.type == self.NodeType.MUX:
                    for drv_key, pin in node.inp.items():
                        if node.sel == pin:
                            assert drv_key in nodes, drv_key
                            net = nodes[drv_key].net
                        else:
                            net = None

                        dst_name = "{}_{}_{}".format(
                            stage_type, key2str(key), pin
                        )
                        if isinstance(drv_key, str):
                            src_name = "{}_inp_{}".format(
                                stage_type, key2str(drv_key)
                            )
                        else:
                            src_name = "{}_{}".format(
                                stage_type, key2str(drv_key)
                            )

                        color = edge_colors[net]

                        dot.append(
                            "    \"{}\" -> \"{}\" [color=\"{}\"];".format(
                                src_name,
                                dst_name,
                                color,
                            )
                        )

                else:
                    assert False, node.type

            # Stage footer
            dot.append("  }")

        # Add footer
        dot.append("}")
        return "\n".join(dot)


# =============================================================================


def main():

    # Parse arguments
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter
    )

    parser.add_argument(
        "--techfile",
        type=str,
        required=True,
        help="Quicklogic 'TechFile' XML file"
    )
    parser.add_argument(
        "--fasm",
        type=str,
        default="default.fasm",
        help="Output FASM file name"
    )
    parser.add_argument(
        "--device",
        type=str,
        choices=["eos-s3"],
        default="eos-s3",
        help="Device name to generate the FASM file for"
    )
    parser.add_argument(
        "--dump-dot",
        action="store_true",
        help="Dump Graphviz .dot files for each routed switchbox type"
    )
    parser.add_argument(
        "--allow-routing-failures",
        action="store_true",
        help="Skip switchboxes that fail routing"
    )

    args = parser.parse_args()

    # Read and parse the XML file
    xml_tree = ET.parse(args.techfile)
    xml_root = xml_tree.getroot()

    # Load data
    print("Loading data from the techfile...")
    data = import_data(xml_root)
    switchbox_types = data["switchbox_types"]
    switchbox_grid = data["switchbox_grid"]
    tile_types = data["tile_types"]
    tile_grid = data["tile_grid"]

    # Route switchboxes
    print("Making switchbox routes...")

    fasm = []
    fully_routed = 0
    partially_routed = 0

    def input_rank(pin):
        """
        Returns a rank of a switchbox input. Pins with the lowest rank should
        be expanded first.
        """
        if pin.name == "GND":
            return 0
        elif pin.name == "VCC":
            return 1
        elif pin.type not in [SwitchboxPinType.HOP, SwitchboxPinType.GCLK]:
            return 2
        elif pin.type == SwitchboxPinType.HOP:
            return 3
        elif pin.type == SwitchboxPinType.GCLK:
            return 4

        return 99

    # Scan for duplicates
    for switchbox in switchbox_types.values():
        for pin in switchbox.pins:
            pinmap = {}
            for pin_loc in pin.locs:
                key = (
                    switchbox.type, pin_loc.stage_id, pin_loc.switch_id,
                    pin_loc.mux_id
                )
                if (key not in pinmap):
                    pinmap[key] = pin_loc.pin_id
                else:
                    if key in duplicate:
                        duplicate[key].append(pin_loc.pin_id)
                    else:
                        duplicate[key] = [pin_loc.pin_id]

    # Process each switchbox type
    for switchbox in switchbox_types.values():
        print("", switchbox.type)

        # Identify all locations of the switchbox
        locs = [
            loc for loc, type in switchbox_grid.items()
            if type == switchbox.type
        ]

        # Initialize the builder
        builder = SwitchboxConfigBuilder(switchbox)

        # Sort the inputs according to their ranks.
        inputs = sorted(switchbox.inputs.values(), key=input_rank)

        # Propagate them
        for stage in ["STREET", "HIGHWAY"]:
            for pin in inputs:
                if pin.name in builder.stage_inputs(stage):
                    builder.propagate_input(stage, pin.name)

        # Check if all nodes are configured
        routing_failed = not builder.check_nodes()

        # Dump dot
        if args.dump_dot:
            dot = builder.dump_dot()
            fname = "defconfig_{}.dot".format(switchbox.type)
            with open(fname, "w") as fp:
                fp.write(dot)

        # Routing failed
        if routing_failed:
            if not args.allow_routing_failures:
                exit(-1)

        # Stats
        if routing_failed:
            partially_routed += len(locs)
        else:
            fully_routed += len(locs)

        # Emit FASM features for each of them
        for loc in locs:
            fasm.extend(builder.fasm_features(loc))

    print(" Total switchboxes: {}".format(len(switchbox_grid)))
    print(" Fully routed     : {}".format(fully_routed))
    print(" Partially routed : {}".format(partially_routed))

    # Power on all LOGIC cells
    for loc, tile in tile_grid.items():

        # Get the tile type object
        tile_type = tile_types[tile.type]

        # If this tile has a LOGIC cell then emit the FASM feature that
        # enables its power
        if "LOGIC" in tile_type.cells:
            feature = "X{}Y{}.LOGIC.LOGIC.Ipwr_gates.J_pwr_st".format(
                loc.x, loc.y
            )
            fasm.append(feature)

    # Write FASM
    print("Writing FASM file...")
    with open(args.fasm, "w") as fp:
        fp.write("\n".join(fasm))


# =============================================================================

if __name__ == "__main__":
    main()
