#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2022 F4PGA Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
"""
Utilities for handling VTR packed netlist (.net) data

VPR packed netlist format specification:
    https://docs.verilogtorouting.org/en/latest/vpr/file_formats/#packed-netlist-format-net
"""
import re
import lxml.etree as ET

from f4pga.utils.quicklogic.repacker.block_path import PathNode

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


class Connection:
    """
    A class representing a connection of a port pin. For output ports it
    refers to child/sibling block, port and pin while for input ports it refers
    to the parent/sibling block, port and pin.
    """

    # A regex for parsing connection specification
    REGEX = re.compile(r"(?P<driver>\S+)\.(?P<port>\S+)\[(?P<pin>[0-9]+)\]->" r"(?P<interconnect>\S+)")

    def __init__(self, driver, port, pin, interconnect):
        """
        Basic constructor
        """
        self.driver = driver
        self.port = port
        self.pin = pin
        self.interconnect = interconnect

    @staticmethod
    def from_string(spec):
        """
        Parses a specification string. Returns a Connection object

        >>> Connection.from_string("parent.A[3]->interconnect")
        parent.A[3]->interconnect
        >>> Connection.from_string("parent.A->interconnect")
        Traceback (most recent call last):
        ...
        AssertionError: parent.A->interconnect
        >>> Connection.from_string("parent.A[3]")
        Traceback (most recent call last):
        ...
        AssertionError: parent.A[3]
        >>> Connection.from_string("Something")
        Traceback (most recent call last):
        ...
        AssertionError: Something
        """
        assert isinstance(spec, str)

        # Try match
        match = Connection.REGEX.fullmatch(spec)
        assert match is not None, spec

        # Extract data
        return Connection(
            driver=match.group("driver"),
            port=match.group("port"),
            pin=int(match.group("pin")),
            interconnect=match.group("interconnect"),
        )

    def to_string(self):
        """
        Builds a specification string that can be stored in packed netlist
        """
        return "{}.{}[{}]->{}".format(self.driver, self.port, self.pin, self.interconnect)

    def __str__(self):
        return self.to_string()

    def __repr__(self):
        return self.to_string()


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


class Port:
    """
    A class representing a block port. Stores port information such as type
    (direction), bus width and its connections.
    """

    def __init__(self, name, type, width=1, connections=None):
        """
        Basic constructor
        """
        self.name = name
        self.type = type
        self.width = width

        # Sanity check provided port connections
        if connections is not None:
            assert isinstance(connections, dict)

            # Check each entry
            for pin, conn in connections.items():
                assert isinstance(pin, int), pin
                assert pin < self.width, (pin, width)
                assert isinstance(conn, Connection) or isinstance(conn, str), pin

            self.connections = connections

        else:
            self.connections = {}

        # Rotation map
        self.rotation_map = None

    @staticmethod
    def from_etree(elem, type):
        """
        Builds a port class from the packed netlist (XML) representation.
        """
        assert elem.tag == "port", elem.tag
        name = elem.attrib["name"]

        conn = elem.text.strip().split()
        width = len(conn)

        # Remove open connections
        conn = {i: conn[i] for i in range(width) if conn[i] != "open"}

        # Build connection objects. Do that only for ports that specify a
        # connection to another port. Otherwise treat the name as a net name.
        for key in conn.keys():
            if "->" in conn[key]:
                conn[key] = Connection.from_string(conn[key])

        return Port(name, type, width, conn)

    def to_etree(self):
        """
        Converts the port representation to the packed netlist (XML)
        representation.
        """

        # Format connections
        text = []
        for i in range(self.width):
            if i in self.connections:
                text.append(str(self.connections[i]))
            else:
                text.append("open")

        elem = ET.Element("port", attrib={"name": self.name})
        elem.text = " ".join(text)
        return elem

    def __str__(self):
        """
        Returns a user-readable description string
        """
        return "{}[{}:0] ({})".format(self.name, self.width - 1, self.type[0].upper())

    def __repr__(self):
        return str(self)


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


class Block:
    """
    A hierarchical block of a packed netlist.
    """

    def __init__(self, name, instance, mode=None, parent=None):

        # Basic attributes
        self.name = name
        self.instance = instance
        self.mode = mode

        # Identify the block type. FIXME: Use a regex here
        self.type = instance.split("[", maxsplit=1)[0]

        # Ports indexed by names
        self.ports = {}

        # Parent block
        self.parent = parent

        # Child blocks indexed by instance
        self.blocks = {}

        # Leaf block attributes and parameters
        self.attributes = {}
        self.parameters = {}

    @staticmethod
    def from_etree(elem):
        """
        Builds a block class from the packed netlist (XML) representation.
        """
        assert elem.tag == "block", elem.tag

        # Create the block with basic attributes
        block = Block(name=elem.attrib["name"], instance=elem.attrib["instance"], mode=elem.get("mode", "default"))

        # Parse ports
        rotation_maps = {}
        for tag in ["inputs", "outputs", "clocks"]:
            port_type = tag[:-1]

            xml_ports = elem.find(tag)
            if xml_ports is not None:
                for xml_port in xml_ports:

                    # Got a port rotation map
                    if xml_port.tag == "port_rotation_map":
                        port_name = xml_port.attrib["name"]
                        rotation = xml_port.text

                        # Parse the map
                        rotation_map = {}
                        for i, j in enumerate(rotation.strip().split()):
                            if j != "open":
                                rotation_map[i] = int(j)

                        # Store it to be later associated with a port
                        rotation_maps[port_name] = rotation_map

                    # Got a port
                    else:
                        port = Port.from_etree(xml_port, port_type)
                        block.ports[port.name] = port

        # Associate rotation maps with ports
        for port_name, rotation_map in rotation_maps.items():
            assert port_name in block.ports, port_name
            block.ports[port_name].rotation_map = rotation_map

        # Recursively parse sub-blocks
        for xml_block in elem.findall("block"):

            sub_block = Block.from_etree(xml_block)

            sub_block.parent = block
            block.blocks[sub_block.instance] = sub_block

        # Parse attributes and parameters
        for tag, data in zip(["attributes", "parameters"], [block.attributes, block.parameters]):

            # Find the list
            xml_list = elem.find(tag)
            if xml_list is not None:

                # Only a leaf block can have attributes / parameters
                assert block.is_leaf, "Non-leaf block '{}' with {}".format(block.instance, tag)

                # Parse
                sub_tag = tag[:-1]
                for xml_item in xml_list.findall(sub_tag):
                    data[xml_item.attrib["name"]] = xml_item.text

        return block

    def to_etree(self):
        """
        Converts the block representation to the packed netlist (XML)
        representation.
        """

        # Base block element
        attrib = {
            "name": self.name,
            "instance": self.instance,
        }
        if not self.is_leaf:
            attrib["mode"] = self.mode if self.mode is not None else "default"

        elem = ET.Element("block", attrib)

        # If this is an "open" block then skip the remaining tags
        if self.name == "open":
            return elem

        # Attributes / parameters
        if self.is_leaf:
            for tag, data in zip(["attributes", "parameters"], [self.attributes, self.parameters]):

                xml_list = ET.Element(tag)

                sub_tag = tag[:-1]
                for key, value in data.items():
                    xml_item = ET.Element(sub_tag, {"name": key})
                    xml_item.text = value
                    xml_list.append(xml_item)

                elem.append(xml_list)

        # Ports
        for tag in ["inputs", "outputs", "clocks"]:
            xml_ports = ET.Element(tag)
            port_type = tag[:-1]

            keys = self.ports.keys()
            for key in keys:
                port = self.ports[key]
                if port.type == port_type:

                    # Encode port
                    xml_port = port.to_etree()
                    xml_ports.append(xml_port)

                    # Rotation map
                    if port.rotation_map:

                        # Encode
                        rotation = []
                        for i in range(port.width):
                            rotation.append(str(port.rotation_map.get(i, "open")))

                        # Make an element
                        xml_rotation_map = ET.Element("port_rotation_map", {"name": port.name})
                        xml_rotation_map.text = " ".join(rotation)
                        xml_ports.append(xml_rotation_map)

            elem.append(xml_ports)

        # Recurse
        keys = self.blocks.keys()
        for key in keys:
            xml_block = self.blocks[key].to_etree()
            elem.append(xml_block)

        return elem

    @property
    def is_leaf(self):
        """
        Returns True when the block is a leaf block
        """
        return len(self.blocks) == 0

    @property
    def is_open(self):
        """
        Returns True when the block is open
        """
        return self.name == "open"

    @property
    def is_route_throu(self):
        """
        Returns True when the block is a route-throu native LUT
        """

        # VPR stores route-through LUTs as "open" blocks with mode set to
        # "wire".
        return self.is_leaf and self.name == "open" and self.mode == "wire"

    def get_path(self, with_indices=True, with_modes=True, default_modes=True):
        """
        Returns the full path to the block. When with_indices is True then
        index suffixes '[<index>]' are appended to block types. When
        with_modes is True then mode suffixes '[<mode>]' are appended. The
        default_modes flag controls appending suffixes for default modes.
        """
        path = []
        block = self

        # Walk towards the tree root
        while block is not None:

            # Type or type with index (instance)
            if with_indices:
                node = block.instance
            else:
                node = block.type

            # Mode suffix
            if not block.is_leaf and with_modes:
                if block.mode != "default" or default_modes:
                    node += "[{}]".format(block.mode)

            # Prepend
            path = [node] + path

            # Go up
            block = block.parent

        return ".".join(path)

    def rename_cluster(self, name):
        """
        Renames this block and all its children except leaf blocks
        """

        def walk(block):

            if not block.is_leaf and not block.is_open:
                block.name = name

            for child in block.blocks.values():
                walk(child)

        walk(self)

    def rename_nets(self, net_map):
        """
        Renames all nets and leaf blocks that drive them according to the
        given map.
        """

        def walk(block):

            # Rename nets in port connections. Check whether the block itself
            # should be renamed as well (output pads need to be).
            rename_block = block.name.startswith("out:")

            for port in block.ports.values():
                for pin, conn in port.connections.items():

                    if isinstance(conn, str):
                        port.connections[pin] = net_map.get(conn, conn)

                        if port.type == "output":
                            rename_block = True

            # Rename the leaf block if necessary
            if block.is_leaf and not block.is_open and rename_block:

                if block.name in net_map:
                    block.name = net_map[block.name]
                elif block.name.startswith("out:"):
                    key = block.name[4:]
                    if key in net_map:
                        block.name = "out:" + net_map[key]

            # Recurse
            for child in block.blocks.values():
                walk(child)

        walk(self)

    def get_neighboring_block(self, instance):
        """
        Returns a neighboring block given in the vicinity of the current block
        given an instance name. The block can be:

         - This block,
         - A child,
         - The parent,
         - A sibling (the parent's child).
        """

        # Strip index. FIXME: Use a regex here.
        block_type = instance.split("[", maxsplit=1)[0]

        # Check self
        if self.instance == instance:
            return self

        # Check children
        if instance in self.blocks:
            return self.blocks[instance]

        # Check parent and siblings
        if self.parent is not None:

            # Parent
            if self.parent.type == block_type:
                return self.parent

            # Siblings
            if instance in self.parent.blocks:
                return self.parent.blocks[instance]

        return None

    def find_net_for_port(self, port, pin):
        """
        Finds net for the given port name and pin index of the block.
        """

        # Get the port
        assert port in self.ports, (self.name, self.instance, (port, pin))
        port = self.ports[port]

        # Unconnected
        if pin not in port.connections:
            return None

        # Get the pin connection
        conn = port.connections[pin]

        # The connection refers to a net directly
        if isinstance(conn, str):
            return conn

        # Get driving block
        block = self.get_neighboring_block(conn.driver)
        assert block is not None, (self.instance, conn.driver)

        # Recurse
        return block.find_net_for_port(conn.port, conn.pin)

    def get_nets(self):
        """
        Returns all nets that are present in this block and its children
        """

        nets = set()

        # Recursive walk function
        def walk(block):

            # Examine block ports
            for port in block.ports.values():
                for pin in range(port.width):

                    net = block.find_net_for_port(port.name, pin)
                    if net:
                        nets.add(net)

        # Get the nets
        walk(self)
        return nets

    def get_block_by_path(self, path):
        """
        Returns a child block given its hierarchical path. The path must not
        include the current block.

        The path may or may not contain modes. When a mode is given it will
        be used for matching. The path must contain indices.
        """

        def walk(block, parts):

            # Check if instance matches
            instance = "{}[{}]".format(parts[0].name, parts[0].index)
            if block.instance != instance:
                return None

            # Check if operating mode matches
            if parts[0].mode is not None:
                if block.mode != parts[0].mode:
                    return None

            # Next
            parts = parts[1:]

            # No more path parts, this is the block
            if not parts:
                return block

            # Find child block by its instance and recurse
            instance = "{}[{}]".format(parts[0].name, parts[0].index)
            if instance in block.blocks:
                return walk(block.blocks[instance], parts)

            return None

        # Prepend self to the path
        path = "{}[{}]".format(self.instance, self.mode) + "." + path

        # Split and parse the path
        path = path.split(".")
        path = [PathNode.from_string(p) for p in path]

        # Find the child
        return walk(self, path)

    def count_leafs(self):
        """
        Counts all non-open leaf blocks
        """

        def walk(block, count=0):

            # This is a non-ope leaf, count it
            if block.is_leaf and not block.is_open:
                count += 1

            # This is a non-leaf block. Recurse
            if not block.is_leaf:
                for child in block.blocks.values():
                    count += walk(child)

            return count

        # Recursive walk and count
        return walk(self)

    def __str__(self):
        """
        Returns a user-readable description string
        """
        ref = self.instance
        if self.mode is not None:
            ref += "[{}]".format(self.mode)
        ref += " ({})".format(self.name)
        return ref

    def __repr__(self):
        return str(self)


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


class PackedNetlist:
    """
    A VPR Packed netlist representation.

    The packed netlist is organized as one huge block representing the whole
    FPGA with all placeable blocks (CLBs) as its children. Here we store the
    top-level block implicitly so all blocks mentioned in a PackedNetlist
    instance refer to individual placeable CLBs.
    """

    def __init__(self):
        """
        Basic constructor
        """

        # Architecture and atom netlist ids
        self.arch_id = None
        self.netlist_id = None

        # Top-level block name and instance
        self.name = None
        self.instance = None

        # Top-level ports (net names)
        self.ports = {
            "inputs": [],
            "outputs": [],
            "clocks": [],
        }

        # CLBs
        self.blocks = {}

    @staticmethod
    def from_etree(root):
        """
        Reads the packed netlist from the given element tree
        """
        assert root.tag == "block", root.tag

        netlist = PackedNetlist()
        netlist.name = root.attrib["name"]
        netlist.instance = root.attrib["instance"]

        netlist.arch_id = root.get("architecture_id", None)
        netlist.netlist_id = root.get("atom_netlist_id", None)

        # Parse top-level ports
        for tag in ["inputs", "outputs", "clocks"]:
            xml_ports = root.find(tag)
            if xml_ports is not None and xml_ports.text:
                netlist.ports[tag] = xml_ports.text.strip().split()

        # Parse CLBs
        for xml_block in root.findall("block"):
            block = Block.from_etree(xml_block)
            netlist.blocks[block.instance] = block

        return netlist

    def to_etree(self):
        """
        Builds an element tree (XML) that represents the packed netlist
        """

        # Top-level root block
        attr = {
            "name": self.name,
            "instance": self.instance,
        }

        if self.arch_id is not None:
            attr["architecture_id"] = self.arch_id
        if self.netlist_id is not None:
            attr["atom_netlist_id"] = self.netlist_id

        root = ET.Element("block", attr)

        # Top-level ports
        for tag in ["inputs", "outputs", "clocks"]:
            xml_ports = ET.Element(tag)
            xml_ports.text = " ".join(self.ports[tag])
            root.append(xml_ports)

        # CLB blocks
        keys = self.blocks.keys()
        for key in keys:
            xml_block = self.blocks[key].to_etree()
            root.append(xml_block)

        return root
