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

PlaceConstraint = namedtuple('PlaceConstraint', '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}'


def get_root_cluster(curr):
    while True:
        parent = curr.getparent()
        if parent is None:
            return None

        parent_parent = parent.getparent()
        if parent_parent is None:
            return curr

        curr = parent


class PlaceConstraints(object):
    def __init__(self, net_file):
        self.constraints = OrderedDict()
        self.block_to_loc = dict()

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

    def load_loc_sites_from_net_file(self):
        """
        .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.
        """
        self.net_to_block = {}
        self.block_to_root_block = {}

        for el in self.net_root.iter('block'):
            root_block = get_root_cluster(el)
            if root_block is not None:
                self.block_to_root_block[el.attrib['name']
                                         ] = root_block.attrib['name']

        for attr in self.net_root.xpath("//attribute"):
            name = attr.attrib["name"]
            if name != 'LOC':
                continue

            # Get block name
            top_block = attr.getparent()
            assert top_block is not None
            while top_block.getparent() is not self.net_root:
                assert top_block is not None
                top_block = top_block.getparent()

            self.block_to_loc[top_block.get("name")] = attr.text

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

        place_constraint = PlaceConstraint(
            name=block_name,
            x=loc[0],
            y=loc[1],
            z=loc[2],
            comment=comment,
        )

        root_block = self.block_to_root_block[block_name]

        self.constraints[root_block] = place_constraint

    def output_place_constraints(self, f):
        if not self.constraints:
            return

        max_name_length = max(len(c.name) for c in self.constraints.values())

        constrained_blocks = {}

        for vpr_net, constraint in self.constraints.items():
            name = constraint.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 get_loc_sites(self):
        """Yields user-constraints (block, location) pairs"""

        if self.block_to_loc is None:
            return

        for loc in self.block_to_loc:
            yield (loc, self.block_to_loc[loc])

    def get_used_instances(self, instance):
        """
        Returns a list containing the root clusters of the specified instances in the packed netlist
        that are marked as used.

        An instance is marked as used when the XML element relative to the instance name has
        children tags.

        E.g.:
            <block name="idelayctrl_block" instance="IDELAYCTRL[0]">
                <inputs>
                    <port name="REFCLK">refclk</port>
                </inputs>
                ...
            </block>
            ...

            <block name="open" instance="IDELAYCTRL[0]" />
        """

        instances = list()

        for el in self.net_root.iter('block'):
            inst = el.attrib['instance']
            if instance in inst:
                if len(el.getchildren()) != 0:
                    instances.append(get_root_cluster(el).attrib['name'])

        return instances
