#!/usr/bin/env python3
import lxml.etree as ET
from enum import Enum


def clog2(x):
    """Ceiling log 2 of x.

    >>> clog2(0), clog2(1), clog2(2), clog2(3), clog2(4)
    (0, 0, 1, 2, 2)
    >>> clog2(5), clog2(6), clog2(7), clog2(8), clog2(9)
    (3, 3, 3, 3, 4)
    >>> clog2(1 << 31)
    31
    >>> clog2(1 << 63)
    63
    >>> clog2(1 << 11)
    11
    """
    x -= 1
    i = 0
    while True:
        if x <= 0:
            break
        x = x >> 1
        i += 1
    return i


def add_metadata(tag, mtype, msubtype):
    meta_root = ET.SubElement(tag, 'metadata')
    meta_type = ET.SubElement(meta_root, 'meta', {'key': 'type'})
    meta_type.text = mtype
    meta_subtype = ET.SubElement(meta_root, 'meta', {'key': 'subtype'})
    meta_subtype.text = msubtype


class MuxType(Enum):
    LOGIC = 'BEL_MX'
    ROUTING = 'BEL_RX'


class MuxPinType(Enum):
    INPUT = 'i'
    SELECT = 's'
    OUTPUT = 'o'

    def verilog(self):
        if self in (self.INPUT, self.SELECT):
            return "input wire"
        elif self == self.OUTPUT:
            return "output wire"
        else:
            raise TypeError(
                "Can't convert {} into verilog definition.".format(self)
            )

    def direction(self):
        if self in (self.INPUT, self.SELECT):
            return "input"
        elif self == self.OUTPUT:
            return "output"
        else:
            raise TypeError(
                "Can't convert {} into verilog definition.".format(self)
            )

    def __str__(self):
        return self.value


class ModulePort(object):
    def __init__(self, pin_type, name, width, index, data_width=1):
        self.name = name
        self.pin_type = pin_type
        self.width = width
        self.index = index
        self.data_width = data_width

    def getParameterString(self):
        if self.width == 1:
            return '\tparameter [0:0] %s = 0;\n' % (self.name)
        else:
            return '\tparameter %s %s = 0;\n' % (self.index, self.name)

    def getDefinition(self):
        if self.width == 1:
            if self.data_width is not None and self.data_width > 1:
                return '\t%s [%d:0] %s;\n' % (
                    self.pin_type.verilog(), self.data_width - 1, self.name
                )
            else:
                return '\t%s %s;\n' % (self.pin_type.verilog(), self.name)
        else:
            return '\t%s %s %s;\n' % (
                self.pin_type.verilog(), self.index, self.name
            )


def pb_type_xml(mux_type, mux_name, pins, subckt=None, num_pb=1, comment=""):
    """Generate <pb_type> XML for a mux.

    Parameters
    ----------
    mux_type: MuxType
        Type of mux to create.

    mux_name: str
        Name of the mux.

    pins: [(MuxPinType, str, int, int),]
        List of tuples which contain (pin type, pin name, port width, index)

    subckt: str
        Name of the blif_model for the mux. Only valid when mux_type ==
        MuxType.LOGIC.

    num_pb: int
        Value for the num_pb value. Defaults to 1.

    comment: str
        Optional comment for the mux.

    Returns
    -------
    xml.etree.ElementTree
        pb_type.xml for requested mux
    """
    assert isinstance(comment,
                      str), "{} {}".format(type(comment), repr(comment))

    if mux_type not in (MuxType.LOGIC, MuxType.ROUTING):
        assert False, "Unknown type {}".format(mux_type)

    pb_type_xml = ET.Element(
        'pb_type', {
            'name': mux_name,
            'num_pb': str(num_pb),
        }
    )

    if mux_type == MuxType.LOGIC:
        pb_type_xml.attrib['blif_model'] = '.subckt %s' % subckt
    else:
        assert not subckt, "Provided subckt={} for non-logic mux!".format(
            subckt
        )

    if comment is not None:
        pb_type_xml.append(ET.Comment(comment))

    for port in pins:
        #assert port.index < port.width, (
        #    "Pin index {} >= width {} for pin {} {}".format(port.index, port.width, port.name, port.pin_type))
        if mux_type == MuxType.ROUTING and port.pin_type == MuxPinType.SELECT:
            continue

        assert port.width == 1 or port.data_width == 1, 'Only one of width(%d) or data_width(%d) may > 1 for pin %s' % (
            port.width, port.data_width, port.name
        )

        if port.width == 1 and port.data_width > 1:
            num_pins = port.data_width
        else:
            num_pins = port.width

        mux = ET.SubElement(
            pb_type_xml,
            port.pin_type.direction(),
            {
                'name': port.name,
                'num_pins': str(num_pins)
            },
        )
        add_metadata(mux, 'bel', 'mux')

    if mux_type == MuxType.LOGIC:
        for inport in pins:
            if inport.pin_type not in (MuxPinType.INPUT, MuxPinType.SELECT):
                continue

            for outport in pins:
                if outport.pin_type not in (MuxPinType.OUTPUT, ):
                    continue

                ET.SubElement(
                    pb_type_xml,
                    'delay_constant',
                    {
                        'max': "10e-12",
                        'in_port': "%s" % inport.name,
                        'out_port': "%s" % outport.name,
                    },
                )
    elif mux_type == MuxType.ROUTING:
        interconnect = ET.SubElement(pb_type_xml, 'interconnect')

        inputs = [
            "{}.{}".format(mux_name, port.name)
            for port in pins
            if port.pin_type in (MuxPinType.INPUT, )
        ]
        outputs = [
            "{}.{}".format(mux_name, port.name)
            for port in pins
            if port.pin_type in (MuxPinType.OUTPUT, )
        ]
        assert len(outputs) == 1

        mux = ET.SubElement(
            interconnect,
            'mux',
            {
                'name': '%s' % mux_name,
                'input': " ".join(inputs),
                'output': outputs[0],
            },
        )
        add_metadata(mux, 'bel', 'routing')

    return pb_type_xml


if __name__ == "__main__":
    import doctest
    doctest.testmod()
