#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020  The SymbiFlow Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier:	ISC

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
    return meta_root


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 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)
            },
        )

    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],
            },
        )
        meta_root = add_metadata(mux, 'bel', 'routing')

        meta_fasm_mux = ET.SubElement(meta_root, 'meta', {'key': 'fasm_mux'})
        meta_fasm_mux.text = "\n".join(
            [""] + ["{0} = {0}".format(i) for i in inputs] + [""])

    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!"
