#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2020-2022 F4PGA Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

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