#!/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', {'name': 'type'})
    meta_type.text = mtype
    meta_subtype = ET.SubElement(meta_root, 'meta', {'name': '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:
        add_metadata(pb_type_xml, 'bel', 'mux')
    else:
        add_metadata(pb_type_xml, 'bel', 'routing')

    if mux_type == MuxType.LOGIC:
        model = ET.SubElement(pb_type_xml, "blif_model")
        model.text = '.subckt {}'.format(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
                if inport.name.startswith('I'):
                    delay_inport = inport.name[1]
                else:
                    # if it is not IX it must be S
                    delay_inport = "S0"
                # XXX: temporary workaroud
                if mux_name == "F6MUX":
                    maxdel = "10e-12"
                else:
                    maxdel = "{{iopath_{}_OUT}}".format(delay_inport)

                ET.SubElement(
                    pb_type_xml,
                    'delay_constant',
                    {
                        'max': maxdel,
                        '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
    failure_count, test_count = doctest.testmod()
    assert test_count > 0
    assert failure_count == 0, "Doctests failed!"
