#!/usr/bin/env python3
"""
A number of utility functions useful for traversing pb_type hierarchy as
defined in VPR architecture XML file.
"""
import re

import lxml.etree as ET

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


def is_leaf_pbtype(xml_pbtype):
    """
    Returns true when the given pb_type is a leaf.
    """
    assert xml_pbtype.tag == "pb_type", xml_pbtype.tag
    return "blif_model" in xml_pbtype.attrib


def get_parent_pb(xml_pbtype):
    """
    Returns a parent pb_type of the given one or none if it is a top-level
    complex block
    """
    assert xml_pbtype.tag in [
        "pb_type", "mode", "interconnect"
    ], xml_pbtype.tag

    # Get immediate parent
    xml_parent = xml_pbtype.getparent()

    # We've hit the end
    if xml_parent is None or xml_parent.tag == "complexblocklist":
        return None

    # The immediate parent is a mode, jump one more level up
    if xml_parent is not None and xml_parent.tag == "mode":
        xml_parent = xml_parent.getparent()

    return xml_parent


def get_parent_pb_and_mode(xml_pbtype):
    """
    Returns a parent pb_type and mode element for the given pb_type. If there
    are no modes (implicit default mode) then the mode element returned is
    the same as the pb_type element.
    """
    assert xml_pbtype.tag in ["pb_type", "mode"], xml_pbtype.tag

    # Get immediate parent
    xml_parent = xml_pbtype.getparent()

    # We've hit the end
    if xml_parent is None or xml_parent.tag == "complexblocklist":
        return None, None

    assert xml_parent.tag in ["pb_type", "mode"], xml_parent.tag

    # pb_type parent
    if xml_pbtype.tag == "pb_type":

        if xml_parent.tag == "pb_type":
            return xml_parent, xml_parent

        elif xml_parent.tag == "mode":
            return xml_parent.getparent(), xml_parent

    elif xml_pbtype.tag == "mode":

        return xml_parent.getparent(), xml_pbtype


def get_pb_by_name(xml_parent, name):
    """
    Searches for a pb_type with the given name inside a parent pb_type.
    Returns either a child or the parent.

    The provided parent may be a mode but a pb_type is always returned.
    """
    assert xml_parent.tag in ["pb_type", "mode"], xml_parent.tag

    # Check the parent name. If this is a mode then check its parent name
    if xml_parent.tag == "mode":
        xml_parent_pb = get_parent_pb(xml_parent)
        if xml_parent_pb.attrib["name"] == name:
            return xml_parent_pb

    else:
        if xml_parent.attrib["name"] == name:
            return xml_parent

    # Check children
    for xml_pbtype in xml_parent.findall("pb_type"):
        if xml_pbtype.attrib["name"] == name:
            return xml_pbtype

    # None found
    return None


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


def yield_pb_children(xml_parent):
    """
    Yields all child pb_types and their indices taking into account num_pb.
    """
    for xml_child in xml_parent.findall("pb_type"):
        num_pb = int(xml_child.get("num_pb", 1))
        for i in range(num_pb):
            yield xml_child, i


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

INTERCONNECT_PORT_SPEC_RE = re.compile(
    r"((?P<pbtype>[A-Za-z0-9_]+)(\[(?P<indices>[0-9:]+)\])?\.)"
    r"(?P<port>[A-Za-z0-9_]+)(\[(?P<bits>[0-9:]+)\])?"
)


def get_pb_and_port(xml_ic, port_spec):
    """
    """
    assert xml_ic.tag == "interconnect"

    # Match the port name
    match = INTERCONNECT_PORT_SPEC_RE.fullmatch(port_spec)
    assert match is not None, port_spec

    # Get the referenced pb_type
    xml_parent = xml_ic.getparent()
    xml_pbtype = get_pb_by_name(xml_parent, match.group("pbtype"))
    assert xml_pbtype is not None, port_spec

    # Find the port
    port = match.group("port")
    for xml_port in xml_pbtype:
        if xml_port.tag in ["input", "output", "clock"]:

            # Got it
            if xml_port.attrib["name"] == port:
                return xml_pbtype, xml_port
    else:
        assert False, (port_spec, xml_pbtype.attrib["name"], port)


def yield_indices(index_spec):
    """
    Given an index specification string as "<i1>:<i0>" or "<i>" yields all bits
    that it is comprised of. The function also supports cases when i0 > i1.
    """

    # None
    if index_spec is None:
        return

    # Range
    elif ":" in index_spec:
        i0, i1 = [int(i) for i in index_spec.split(":")]

        if i0 > i1:
            for i in range(i1, i0 + 1):
                yield i

        elif i0 < i1:
            for i in range(i0, i1 + 1):
                yield i

        else:
            yield i0

    # Single value
    else:
        yield int(index_spec)


def yield_pins(xml_ic, port_spec, skip_index=True):
    """
    Yields individual port pins as "<pb_type>[<pb_index].<port>[<bit>]" given
    the port specification.
    """
    assert xml_ic.tag == "interconnect"

    # Match the port name
    match = INTERCONNECT_PORT_SPEC_RE.fullmatch(port_spec)
    assert match is not None, port_spec

    # Get the referenced pb_type
    xml_parent = xml_ic.getparent()
    xml_pbtype = get_pb_by_name(xml_parent, match.group("pbtype"))
    assert xml_pbtype is not None, port_spec

    # Find the port
    port = match.group("port")
    for xml_port in xml_pbtype:
        if xml_port.tag in ["input", "output", "clock"]:
            if xml_port.attrib["name"] == port:
                width = int(xml_port.attrib["num_pins"])
                break
    else:
        assert False, (port_spec, xml_pbtype.attrib["name"], port)

    # Check if we are referencing an upstream parent
    is_parent_port = get_parent_pb(xml_ic) == xml_pbtype

    # Build a list of pb_type indices
    if not is_parent_port:
        num_pb = int(xml_pbtype.get("num_pb", 1))
        indices = list(yield_indices(match.group("indices")))
        if not indices:
            if num_pb > 1:
                indices = list(range(0, num_pb))
            else:
                indices = [None]
    else:
        indices = [None]

    # Build a list of bit indices
    bits = list(yield_indices(match.group("bits")))
    if not bits:
        if width > 1:
            bits = list(range(0, width))
        else:
            bits = [None]

    # Yield individual pin names
    for i in indices:
        for j in bits:

            name = match.group("pbtype")
            if i is not None:
                name += "[{}]".format(i)
            elif not skip_index:
                name += "[0]"

            name += "." + match.group("port")
            if j is not None:
                name += "[{}]".format(j)
            elif not skip_index:
                name += "[0]"

            yield name


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


def append_metadata(xml_item, meta_name, meta_data):
    """
    Appends metadata to an element of architecture
    """
    assert xml_item.tag in ["pb_type", "mode", "direct", "mux"]

    xml_meta = ET.Element("meta", {"name": meta_name})
    xml_meta.text = meta_data

    # Use existing metadata section. If not present then create a new one
    xml_metadata = xml_item.find("metadata")
    if xml_metadata is None:
        xml_metadata = ET.Element("metadata")

    # Append meta, check for conflict
    for item in xml_metadata.findall("meta"):
        assert item.attrib["name"] != xml_meta.attrib["name"]
    xml_metadata.append(xml_meta)

    # Append
    if xml_metadata.getparent() is None:
        xml_item.append(xml_metadata)
