#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019-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

from __future__ import print_function
from collections import OrderedDict, namedtuple
import itertools
import re
import lxml.etree as ET

from f4pga.utils.eblif import parse_blif

IoConstraint = namedtuple("IoConstraint", "name x y z comment")

HEADER_TEMPLATE = """\
#{name:<{nl}} x   y   z    pcf_line
#{s:-^{nl}} --  --  -    ----"""

CONSTRAINT_TEMPLATE = "{name:<{nl}} {x: 3} {y: 3} {z: 2}  # {comment}"
INOUT_REGEX = re.compile(r"^(.+)(_\$inp|_\$out)(.*)$")
NETNAME_REGEX = re.compile(r"(.+?)(\[[0-9]+\]$|$)")


class IoPlace(object):
    def __init__(self):
        self.constraints = OrderedDict()
        self.inputs = set()
        self.outputs = set()
        self.net_to_block = None
        self.net_map = {}
        self.block_to_inst = {}
        self.inout_nets = set()
        self.net_to_pad = set()
        self.net_file_io = set()

    def read_io_loc_pairs(self, blif):
        """
        Read IO_LOC_PAIRS parameters from eblif carrying the information
        which package pin a specified top port is constrained, e.g. O_LOC_PAIRS = "portA:D1"
        In case of differential inputs/outputs there are two pairs of the parameter,
        i.e. IO_LOC_PAIRS = "portA_p:D2,portA_n:D4"
        """
        if "subckt" not in blif:
            return
        for attr in blif["subckt"]:
            if "param" not in attr:
                continue
            if "IO_LOC_PAIRS" in attr["param"]:
                locs = attr["param"]["IO_LOC_PAIRS"][1:-1].split(",")
                if "NONE" in locs:
                    continue
                for loc in locs:
                    net, pad = loc.split(":")
                    self.net_to_pad.add((net, pad))

    def read_io_list_from_eblif(self, eblif_file):
        blif = parse_blif(eblif_file)

        self.inputs = set(blif["inputs"]["args"])
        self.outputs = set(blif["outputs"]["args"])

        # Build a net name map that maps products of an inout port split into
        # their formet name.
        #
        # For example, an inout port 'A' is split into 'A_$inp' and 'A_$out',
        # port B[2] into 'B_$inp[2]' and 'B_$out[2]'.
        self.net_map = {}
        self.inout_nets = set()
        for net in itertools.chain(self.inputs, self.outputs):
            match = INOUT_REGEX.match(net)
            if match:
                alias = match.group(1) + match.group(3)
                self.inout_nets.add(alias)
                self.net_map[net] = alias
            else:
                self.net_map[net] = net
        self.read_io_loc_pairs(blif)

    def load_block_names_from_net_file(self, net_file):
        """
        .place files expect top-level block (cluster) names, not net names, so
        build a mapping from net names to block names from the .net file.
        """
        net_xml = ET.parse(net_file)
        net_root = net_xml.getroot()
        self.net_to_block = {}

        for block in net_root.xpath("//block"):
            instance = block.attrib["instance"]
            if instance != "inpad[0]" and instance != "outpad[0]":
                continue

            top_block = block.getparent()
            assert top_block is not None
            while top_block.getparent() is not net_root:
                assert top_block is not None
                top_block = top_block.getparent()
            self.net_to_block[block.get("name")] = top_block.get("name")

        # Loop over all top-level blocks. Store block name to its instance
        # correspondences.
        for block_xml in net_root.findall("block"):
            name = block_xml.attrib["name"]
            inst = block_xml.attrib["instance"]

            assert name not in self.block_to_inst, block_xml.attrib
            self.block_to_inst[name] = inst

    def load_net_file_ios(self, net_file):
        """
        Loads input and outputs net names from the netlist file.
        """

        def get_ios(net_root, io_types):
            "Get the top level io signals from the netlist XML root."
            for io_type in io_types:
                io = net_root.xpath("/block/{}/text ()".format(io_type))

                if len(io) == 1:
                    yield io[0]

        net_xml = ET.parse(net_file)
        net_root = net_xml.getroot()

        for io_line in get_ios(net_root, ["inputs", "outputs"]):
            io_list = io_line.split(" ")
            for io in io_list:
                self.net_file_io.add(io.replace("out:", ""))

    def get_top_level_block_instance_for_net(self, net_name):
        """
        Returns a name of the top-level block instance for the given net
        name.
        """
        assert self.is_net(net_name)

        # VPR prefixes output constraints with "out:"
        if net_name in self.outputs:
            net_name = "out:" + net_name

        # This is an inout net
        if net_name in self.inout_nets:
            block_names = set()

            for prefix, suffix in zip(["", "out:"], ["_$inp", "_$out"]):
                match = NETNAME_REGEX.match(net_name)
                name = prefix + match.group(1) + suffix + match.group(2)
                block_names.add(self.net_to_block[name])

            # Both parts of the net should point to the same block
            assert len(block_names) == 1, (net_name, block_names)
            return self.block_to_inst[list(block_names)[0]]

        # A regular net
        else:
            if net_name in self.net_to_block:
                block_name = self.net_to_block[net_name]
                return self.block_to_inst[block_name]
            else:
                return None

    def constrain_net(self, net_name, loc, comment=""):
        assert len(loc) == 3
        assert net_name not in self.constraints

        assert self.is_net(net_name), "net {} not in eblif".format(net_name)

        # VPR prefixes output constraints with "out:"
        if net_name in self.outputs:
            net_name = "out:" + net_name

        # This is an inout net
        if net_name in self.inout_nets:
            for prefix, suffix in zip(["", "out:"], ["_$inp", "_$out"]):
                match = NETNAME_REGEX.match(net_name)
                name = prefix + match.group(1) + suffix + match.group(2)

                self.constraints[name] = IoConstraint(
                    name=name,
                    x=loc[0],
                    y=loc[1],
                    z=loc[2],
                    comment=comment,
                )

        # A regular net
        else:
            self.constraints[net_name] = IoConstraint(
                name=net_name,
                x=loc[0],
                y=loc[1],
                z=loc[2],
                comment=comment,
            )

    def output_io_place(self, f):
        max_name_length = max(len(c.name) for c in self.constraints.values())
        print(HEADER_TEMPLATE.format(name="Block Name", nl=max_name_length, s=""), file=f)

        constrained_blocks = {}

        for vpr_net, constraint in self.constraints.items():
            name = constraint.name
            name = self.net_to_block.get(name) if self.net_to_block else name

            # This block is already constrained, check if there is no
            # conflict there.
            if name in constrained_blocks:
                existing = constrained_blocks[name]

                if existing.x != constraint.x or existing.y != constraint.y or existing.z != constraint.z:
                    print("Error: block '{}' has multiple conflicting constraints!".format(name))
                    print("", constrained_blocks[name])
                    print("", constraint)
                    exit(-1)

                # Don't write the second constraing
                continue

            # omit if no corresponding block name for the net
            if name is not None:
                print(
                    CONSTRAINT_TEMPLATE.format(
                        name=name,
                        nl=max_name_length,
                        x=constraint.x,
                        y=constraint.y,
                        z=constraint.z,
                        comment=constraint.comment,
                    ),
                    file=f,
                )

                # Add to constrained block list
                constrained_blocks[name] = constraint

    def is_net(self, net):
        return net in self.net_map.values()

    def is_net_packed(self, net):
        return net in self.net_file_io

    def get_nets(self):
        for net in self.inputs:
            yield self.net_map[net]
        for net in self.outputs:
            yield self.net_map[net]
