#!/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
