""" rr graph library that is not tied to the underlying serialization format
and provides simple fast lookup required to build real FPGA rr graph fabrics.
"""

from __future__ import print_function
from collections import namedtuple
from enum import Enum
from .tracks import Track
from lib.rr_graph import channel2
from lib import progressbar_utils


class SwitchType(Enum):
    """Enumeration of allowed VPR switch type
    See: https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-switches-switch
    """  # noqa: E501
    INVALID_SWITCH_TYPE = 0
    MUX = 1
    TRISTATE = 2
    PASS_GATE = 3
    SHORT = 4
    BUFFER = 5


class NodeType(Enum):
    """VPR Node type. This is a superset of Type in channel.py
    See: https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-nodes-node
    """  # noqa: E501
    INVALID_NODE_TYPE = 0
    CHANX = 1
    CHANY = 2
    SOURCE = 3
    SINK = 4
    OPIN = 5
    IPIN = 6


class NodeDirection(Enum):
    """VPR Node Direction. This is a superset of Direction in channel.py
    See: https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-nodes-node
    """  # noqa: E501
    NO_DIR = 0
    INC_DIR = 1
    DEC_DIR = 2
    BI_DIR = 3


class PinType(Enum):
    """Enum for PinClass type
    See: https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-blocks-pin_class
    """  # noqa: E501
    NONE = 0
    OPEN = 1
    OUTPUT = 2
    INPUT = 3


class ChannelList(namedtuple('ChannelList', 'index info')):
    """VPR `x_list` and `y_list` tags in the channels
    """


class Channels(namedtuple(
        'Channels', 'chan_width_max x_min y_min x_max y_max x_list y_list')):
    """Encapsulation for VPR channels tag
    See: https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-channel-channel
    """  # noqa: E501


class SwitchTiming(namedtuple('SwitchTiming',
                              'r c_in c_out c_internal t_del')):
    """Encapsulation for timing attributes of a VPR switch
    see: https://vtr-verilog-to-routing.readthedocs.io/en/latest/arch/reference.html#switches
    """


class SwitchSizing(namedtuple('SwitchSizing', 'mux_trans_size buf_size')):
    """Encapsulation for sizing attributes of a VPR switch
    see: https://vtr-verilog-to-routing.readthedocs.io/en/latest/arch/reference.html#switches
    """


class Switch(namedtuple('Switch', 'id name type timing sizing')):
    """Encapsulate VPR switch tag. Contains SwitchTiming and SwitchSizing tuples.
    see: https://vtr-verilog-to-routing.readthedocs.io/en/latest/arch/reference.html#switches
    """


class SegmentTiming(namedtuple('SegmentTiming', 'r_per_meter c_per_meter')):
    """Encapsulation for timing attributes of a VPR segment.
    see: https://vtr-verilog-to-routing.readthedocs.io/en/latest/arch/reference.html#wire-segments
    """


class Segment(namedtuple('Segment', 'id name timing')):
    """Encapsulate VPR segment tag. Contains SegmentTiming to encapsulate the timing attributes
    see: https://vtr-verilog-to-routing.readthedocs.io/en/latest/arch/reference.html#wire-segments
    """


class Pin(namedtuple('Pin', 'ptc name')):
    """Encapsulation for VPR Pin tag
    See: https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-blocks-pin
    """  # noqa: E501


class PinClass(namedtuple('PinClass', 'type pin')):
    """Encapsulation for VPR PinClass tag
    See: https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-blocks-pin_class
    """  # noqa: E501


class BlockType(namedtuple('BlockType', 'id name width height pin_class')):
    """Encapsulation for VPR BlockType tag
    See: https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-blocks-block_type
    """  # noqa: E501


class GridLoc(namedtuple('GridLoc',
                         'x y block_type_id width_offset height_offset')):
    """
    """


class NodeTiming(namedtuple('NodeTiming', 'r c')):
    """https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-nodes-timing
    """


class NodeLoc(namedtuple('NodeLoc', 'x_low y_low x_high y_high side ptc')):
    """https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-nodes-loc
    """


class NodeMetadata(namedtuple('NodeMetadata',
                              'name x_offset y_offset z_offset value')):
    """https://vtr-verilog-to-routing.readthedocs.io/en/latest/arch/reference.html#architecture-metadata
    """


class NodeSegment(namedtuple('NodeSegment', 'segment_id')):
    """https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-nodes-segment
    """


class Node(namedtuple(
        'Node', 'id type direction capacity loc timing metadata segment')):
    """https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-nodes-node
    """


class Edge(namedtuple('Edge', 'src_node sink_node switch_id metadata')):
    """https://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#tag-edges-edge
    """


class GraphInput(namedtuple('GraphInput',
                            'switches segments block_types grid')):
    """Top level encapsulation of input Graph
    """


def process_track(track):
    channel_model = channel2.Channel(track)
    channel_model.pack_tracks()

    return channel_model


class Graph(object):
    """ Simple object for working with VPR RR graph.

    This class does not handle serialization.  A format specific class handles
    serdes takes.
    """

    def __init__(
            self,
            switches,
            segments,
            block_types,
            grid,
            nodes,
            edges=None,
            build_pin_edges=True
    ):
        self.switches = switches
        self.next_switch_id = max(switch.id for switch in self.switches) + 1

        self.switch_name_map = {}
        self.delayless_switch = None

        for idx, switch in enumerate(self.switches):
            assert idx == switch.id
            assert switch.name not in self.switch_name_map
            self.switch_name_map[switch.name] = switch.id

        assert '__vpr_delayless_switch__' in self.switch_name_map, self.switch_name_map.keys(
        )
        self.delayless_switch = self.switch_name_map['__vpr_delayless_switch__'
                                                     ]

        self.segments = segments
        self.segment_name_map = {}

        for idx, segment in enumerate(self.segments):
            assert idx == segment.id
            assert segment.name not in self.segment_name_map
            self.segment_name_map[segment.name] = segment.id

        self.block_types = block_types
        self.grid = grid

        self.tracks = []
        self.nodes = nodes
        self.nodes.sort(key=lambda node: node.id)
        self.edges = edges if edges is not None else []

        # Map of (x, y) to GridLoc definitions.
        self.loc_map = {}

        # Maps grid location and pin class index to node index
        # (x, y, pin class idx) -> node_idx
        self.loc_pin_class_map = {}

        # Maps grid location and pin index to node index
        # (x, y, pin idx) -> [(node_idx, side)]
        self.loc_pin_map = {}

        # Maps pin name to block type id and pin idx.
        # pin name -> block type id, pin class idx, pin idx
        self.pin_name_map = {}

        self.pin_ptc_to_name_map = {}

        # Create pin_name_map and sanity check block_types.
        for idx, block_type in enumerate(self.block_types):
            assert idx == block_type.id
            for pin_class_idx, pin_class in enumerate(block_type.pin_class):
                for pin in pin_class.pin:
                    assert pin.name not in self.pin_name_map
                    self.pin_name_map[
                        pin.name] = (block_type.id, pin_class_idx, pin.ptc)
                    self.pin_ptc_to_name_map[(block_type.id,
                                              pin.ptc)] = pin.name

        # Create mapping from grid locations and pins to nodes.
        for idx, node in enumerate(self.nodes):
            assert node.id == idx, (idx, node)

            if node.type in (
                    NodeType.IPIN,
                    NodeType.OPIN,
            ):
                key = (node.loc.x_low, node.loc.y_low, node.loc.ptc)
                if key not in self.loc_pin_map:
                    self.loc_pin_map[key] = []
                self.loc_pin_map[key].append((node.id, node.loc.side))

            if node.type in (
                    NodeType.SOURCE,
                    NodeType.SINK,
            ):
                key = (node.loc.x_low, node.loc.y_low, node.loc.ptc)
                assert key not in self.loc_pin_class_map, (
                    node, self.loc_pin_class_map[key]
                )
                self.loc_pin_class_map[key] = node.id

        # Rebuild initial edges of IPIN -> SINK and SOURCE -> OPIN.
        for loc in grid:
            assert loc.block_type_id >= 0 and loc.block_type_id <= len(
                self.block_types
            ), loc.block_type_id
            block_type = self.block_types[loc.block_type_id]

            key = (loc.x, loc.y)
            assert key not in self.loc_map
            self.loc_map[key] = loc

            for pin_class_idx, pin_class in enumerate(block_type.pin_class):
                pin_class_node = self.loc_pin_class_map[
                    (loc.x, loc.y, pin_class_idx)]

                # Skip building IPIN -> SINK and OPIN -> SOURCE graph if edges
                # are not required.
                if not build_pin_edges:
                    continue

                for pin in pin_class.pin:
                    for pin_node, _ in self.loc_pin_map[(loc.x, loc.y,
                                                         pin.ptc)]:
                        if pin_class.type == PinType.OUTPUT:
                            self.add_edge(
                                src_node=pin_class_node,
                                sink_node=pin_node,
                                switch_id=self.delayless_switch
                            )
                        elif pin_class.type == PinType.INPUT:
                            self.add_edge(
                                src_node=pin_node,
                                sink_node=pin_class_node,
                                switch_id=self.delayless_switch,
                            )
                        else:
                            assert False, (loc, pin_class)

    def _create_node(
            self,
            type,
            direction,
            loc,
            segment,
            timing,
            capacity=1,
            metadata=None,
    ):

        if timing is None:
            if type in (NodeType.CHANX, NodeType.CHANY):
                timing = NodeTiming(r=1, c=1)
            else:
                timing = NodeTiming(r=0, c=0)

        self.nodes.append(
            Node(
                id=len(self.nodes),
                type=type,
                direction=direction,
                capacity=capacity,
                loc=loc,
                timing=timing,
                metadata=metadata,
                segment=segment,
            )
        )

        return self.nodes[-1].id

    def get_segment_id_from_name(self, segment_name):
        return self.segment_name_map[segment_name]

    def get_delayless_switch_id(self):
        return self.delayless_switch

    def add_track(
            self,
            track,
            segment_id,
            capacity=1,
            timing=None,
            name=None,
            ptc=None,
            direction=NodeDirection.BI_DIR,
    ):
        """Take a Track and add node to the graph with supplimental data"""

        if track.direction == 'X':
            node_type = NodeType.CHANX
        elif track.direction == 'Y':
            node_type = NodeType.CHANY
        else:
            assert False, track

        if name is not None:
            metadata = [
                NodeMetadata(
                    name=name,
                    x_offset=0,
                    y_offset=0,
                    z_offset=0,
                    value='',
                )
            ]
        else:
            metadata = None

        self.tracks.append(
            self._create_node(
                type=node_type,
                direction=direction,
                capacity=capacity,
                loc=NodeLoc(
                    x_low=track.x_low,
                    y_low=track.y_low,
                    x_high=track.x_high,
                    y_high=track.y_high,
                    side=None,
                    ptc=ptc,
                ),
                timing=timing,
                segment=NodeSegment(segment_id=segment_id),
                metadata=metadata,
            )
        )

        return self.tracks[-1]

    def create_pin_name_from_tile_type_and_pin(
            self, tile_type, port_name, pin_idx=0
    ):
        return '{}.{}[{}]'.format(tile_type, port_name, pin_idx)

    def create_pin_name_from_tile_type_sub_tile_num_and_pin(
            self, tile_type, sub_tile_num, port_name, pin_idx=0
    ):
        return '{}[{}].{}[{}]'.format(
            tile_type, sub_tile_num, port_name, pin_idx
        )

    def get_nodes_for_pin(self, loc, pin_name):
        block_type_id, pin_class_idx, pin_idx = self.pin_name_map[pin_name]
        grid_loc = self.loc_map[loc]
        assert grid_loc.block_type_id == block_type_id

        return self.loc_pin_map[(loc[0], loc[1], pin_idx)]

    def _create_edge(
            self, src_node, sink_node, switch_id, name=None, value=''
    ):
        assert src_node >= 0 and src_node < len(self.nodes), src_node
        assert sink_node >= 0 and sink_node < len(self.nodes), sink_node
        assert switch_id >= 0 and switch_id < len(self.switches), switch_id

        if name is not None:
            metadata = [
                NodeMetadata(
                    name=name, x_offset=0, y_offset=0, z_offset=0, value=value
                )
            ]
        else:
            metadata = None

        return Edge(
            src_node=src_node,
            sink_node=sink_node,
            switch_id=switch_id,
            metadata=metadata
        )

    def add_edge(self, src_node, sink_node, switch_id, name=None, value=''):
        """Add Edge to the graph

        Appends a new edge to the graph and retruns the index in the edges list
        """
        self.edges.append(
            self._create_edge(
                src_node=src_node,
                sink_node=sink_node,
                switch_id=switch_id,
                name=name,
                value=value
            )
        )

        return len(self.edges) - 1

    def add_switch(self, switch):
        """ Inner add_switch method.  Do not invoke directly.

        This method adds a switch into the graph model.  This method should
        not be invoked directly, instead invoke add_switch on the serialization
        graph object (e.g. rr_graph_xml.graph2.add_switch, etc).

        """

        switch_dict = switch._asdict()
        switch_dict['id'] = self.next_switch_id
        self.next_switch_id += 1

        switch = Switch(**switch_dict)

        assert switch.name not in self.switch_name_map
        self.switch_name_map[switch.name] = switch.id
        self.switches.append(switch)

        return switch.id

    def check_ptc(self):
        for node in self.nodes:
            assert node.loc.ptc is not None, node

    def set_track_ptc(self, track, ptc):
        node_d = self.nodes[track]._asdict()
        loc_d = self.nodes[track].loc._asdict()
        assert loc_d['ptc'] is None
        loc_d['ptc'] = ptc
        node_d['loc'] = NodeLoc(**loc_d)

        self.nodes[track] = Node(**node_d)

    def create_channels(self, pad_segment, pool=None):
        """ Pack tracks into channels and return Channels definition for tracks."""
        assert len(self.tracks) > 0

        xs = []
        ys = []

        for track in self.tracks:
            track_node = self.nodes[track]

            xs.append(track_node.loc.x_low)
            xs.append(track_node.loc.x_high)
            ys.append(track_node.loc.y_low)
            ys.append(track_node.loc.y_high)

        x_tracks = {}
        y_tracks = {}

        for track in self.tracks:
            track_node = self.nodes[track]

            if track_node.type == NodeType.CHANX:
                assert track_node.loc.y_low == track_node.loc.y_high

                x1, x2 = sorted((track_node.loc.x_low, track_node.loc.x_high))

                if track_node.loc.y_low not in x_tracks:
                    x_tracks[track_node.loc.y_low] = []

                x_tracks[track_node.loc.y_low].append((x1, x2, track))
            elif track_node.type == NodeType.CHANY:
                assert track_node.loc.x_low == track_node.loc.x_high

                y1, y2 = sorted((track_node.loc.y_low, track_node.loc.y_high))

                if track_node.loc.x_low not in y_tracks:
                    y_tracks[track_node.loc.x_low] = []

                y_tracks[track_node.loc.x_low].append((y1, y2, track))
            else:
                assert False, track_node

        x_list = []
        y_list = []

        x_channel_models = {}
        y_channel_models = {}

        if pool is not None:
            for y in x_tracks:
                x_channel_models[y] = pool.apply_async(
                    process_track, (x_tracks[y], )
                )

            for x in y_tracks:
                y_channel_models[x] = pool.apply_async(
                    process_track, (y_tracks[x], )
                )

        for y in progressbar_utils.progressbar(range(max(x_tracks) + 1)):
            if y in x_tracks:
                if pool is None:
                    x_channel_models[y] = process_track(x_tracks[y])
                else:
                    x_channel_models[y] = x_channel_models[y].get()

                x_list.append(len(x_channel_models[y].trees))
                for idx, tree in enumerate(x_channel_models[y].trees):
                    for i in tree:
                        self.set_track_ptc(track=i[2], ptc=idx)
            else:
                x_list.append(0)

        for x in progressbar_utils.progressbar(range(max(y_tracks) + 1)):
            if x in y_tracks:
                if pool is None:
                    y_channel_models[x] = process_track(y_tracks[x])
                else:
                    y_channel_models[x] = y_channel_models[x].get()

                y_list.append(len(y_channel_models[x].trees))
                for idx, tree in enumerate(y_channel_models[x].trees):
                    for i in tree:
                        self.set_track_ptc(track=i[2], ptc=idx)
            else:
                y_list.append(0)

        x_min = min(xs)
        y_min = min(ys)
        x_max = max(xs)
        y_max = max(ys)

        num_padding = 0
        for chan, channel_model in x_channel_models.items():
            for ptc, start, end in channel_model.fill_empty(max(x_min, 1),
                                                            x_max):
                num_padding += 1
                self.add_track(
                    track=Track(
                        direction='X',
                        x_low=start,
                        y_low=chan,
                        x_high=end,
                        y_high=chan,
                    ),
                    segment_id=pad_segment,
                    capacity=0,
                    timing=None,
                    ptc=ptc
                )

        for chan, channel_model in y_channel_models.items():
            for ptc, start, end in channel_model.fill_empty(max(y_min, 1),
                                                            y_max):
                num_padding += 1
                self.add_track(
                    track=Track(
                        direction='Y',
                        x_low=chan,
                        y_low=start,
                        x_high=chan,
                        y_high=end,
                    ),
                    segment_id=pad_segment,
                    capacity=0,
                    timing=None,
                    ptc=ptc
                )

        print('Number padding nodes {}'.format(num_padding))

        return Channels(
            chan_width_max=max(max(x_list), max(y_list)),
            x_min=x_min,
            y_min=y_min,
            x_max=x_max,
            y_max=y_max,
            x_list=[ChannelList(idx, info) for idx, info in enumerate(x_list)],
            y_list=[ChannelList(idx, info) for idx, info in enumerate(y_list)],
        )

    def block_type_at_loc(self, loc):
        return self.block_types[self.loc_map[loc].block_type_id].name

    def get_switch_id(self, switch_name):
        return self.switch_name_map[switch_name]

    def sort_nodes(self):
        self.nodes.sort(key=lambda node: node.id)
