# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
"""This contains a class which is used to help generate `top_{name}.h` and
`top_{name}.h`.
"""
from collections import OrderedDict
from math import ceil

from mako.template import Template


class Name(object):
    """We often need to format names in specific ways; this class does so."""
    def __add__(self, other):
        return Name(self.parts + other.parts)

    @staticmethod
    def from_snake_case(input):
        return Name(input.split("_"))

    def __init__(self, parts):
        self.parts = list(parts)
        for p in parts:
            assert len(p) > 0, "cannot add zero-length name piece"

    def as_snake_case(self):
        return "_".join([p.lower() for p in self.parts])

    def as_camel_case(self):
        out = ""
        for p in self.parts:
            # If we're about to join two parts which would introduce adjacent
            # numbers, put an underscore between them.
            if out[-1:].isnumeric() and p[:1].isnumeric():
                out += "_" + p
            else:
                out += p.capitalize()
        return out

    def as_c_define(self):
        return "_".join([p.upper() for p in self.parts])

    def as_c_enum(self):
        return "k" + self.as_camel_case()

    def as_c_type(self):
        return self.as_snake_case() + "_t"

    def remove_part(self, part_to_remove):
        return Name([p for p in self.parts if p != part_to_remove])


class MemoryRegion(object):
    def __init__(self, name, base_addr, size_bytes):
        self.name = name
        self.base_addr = base_addr
        self.size_bytes = size_bytes
        self.size_words = ceil(int(str(size_bytes), 0) / 4)

    def base_addr_name(self):
        return self.name + Name(["base", "addr"])

    def offset_name(self):
        return self.name + Name(["offset"])

    def size_bytes_name(self):
        return self.name + Name(["size", "bytes"])

    def size_words_name(self):
        return self.name + Name(["size", "words"])


class CEnum(object):
    def __init__(self, name):
        self.name = name
        self.enum_counter = 0
        self.finalized = False

        self.constants = []

    def add_constant(self, constant_name, docstring=""):
        assert not self.finalized

        full_name = self.name + constant_name

        value = self.enum_counter
        self.enum_counter += 1

        self.constants.append((full_name, value, docstring))

        return full_name

    def add_last_constant(self, docstring=""):
        assert not self.finalized

        full_name = self.name + Name(["last"])

        _, last_val, _ = self.constants[-1]

        self.constants.append((full_name, last_val, r"\internal " + docstring))
        self.finalized = True

    def render(self):
        template = ("typedef enum ${enum.name.as_snake_case()} {\n"
                    "% for name, value, docstring in enum.constants:\n"
                    "  ${name.as_c_enum()} = ${value}, /**< ${docstring} */\n"
                    "% endfor\n"
                    "} ${enum.name.as_c_type()};")
        return Template(template).render(enum=self)


class CArrayMapping(object):
    def __init__(self, name, output_type_name):
        self.name = name
        self.output_type_name = output_type_name

        self.mapping = OrderedDict()

    def add_entry(self, in_name, out_name):
        self.mapping[in_name] = out_name

    def render_declaration(self):
        template = (
            "extern const ${mapping.output_type_name.as_c_type()}\n"
            "    ${mapping.name.as_snake_case()}[${len(mapping.mapping)}];")
        return Template(template).render(mapping=self)

    def render_definition(self):
        template = (
            "const ${mapping.output_type_name.as_c_type()}\n"
            "    ${mapping.name.as_snake_case()}[${len(mapping.mapping)}] = {\n"
            "% for in_name, out_name in mapping.mapping.items():\n"
            "  [${in_name.as_c_enum()}] = ${out_name.as_c_enum()},\n"
            "% endfor\n"
            "};\n")
        return Template(template).render(mapping=self)


class TopGenC(object):
    def __init__(self, top_info):
        self.top = top_info
        self._top_name = Name(["top"]) + Name.from_snake_case(top_info["name"])

        # The .c file needs the .h file's relative path, store it here
        self.header_path = None

        self._init_plic_targets()
        self._init_plic_mapping()
        self._init_alert_mapping()
        self._init_pinmux_mapping()
        self._init_pwrmgr_wakeups()
        self._init_rstmgr_sw_rsts()
        self._init_pwrmgr_reset_requests()
        self._init_clkmgr_clocks()

    def modules(self):
        return [(m["name"],
                 MemoryRegion(self._top_name + Name.from_snake_case(m["name"]),
                              m["base_addr"], m["size"]))
                for m in self.top["module"]]

    def memories(self):
        return [(m["name"],
                 MemoryRegion(self._top_name + Name.from_snake_case(m["name"]),
                              m["base_addr"], m["size"]))
                for m in self.top["memory"]]

    def _init_plic_targets(self):
        enum = CEnum(self._top_name + Name(["plic", "target"]))

        for core_id in range(int(self.top["num_cores"])):
            enum.add_constant(Name(["ibex", str(core_id)]),
                              docstring="Ibex Core {}".format(core_id))

        enum.add_last_constant("Final PLIC target")

        self.plic_targets = enum

    def _init_plic_mapping(self):
        """We eventually want to generate a mapping from interrupt id to the
        source peripheral.

        In order to do so, we generate two enums (one for interrupts, one for
        sources), and store the generated names in a dictionary that represents
        the mapping.

        PLIC Interrupt ID 0 corresponds to no interrupt, and so no peripheral,
        so we encode that in the enum as "unknown".

        The interrupts have to be added in order, with "none" first, to ensure
        that they get the correct mapping to their PLIC id, which is used for
        addressing the right registers and bits.
        """
        sources = CEnum(self._top_name + Name(["plic", "peripheral"]))
        interrupts = CEnum(self._top_name + Name(["plic", "irq", "id"]))
        plic_mapping = CArrayMapping(
            self._top_name + Name(["plic", "interrupt", "for", "peripheral"]),
            sources.name)

        unknown_source = sources.add_constant(Name(["unknown"]),
                                              docstring="Unknown Peripheral")
        none_irq_id = interrupts.add_constant(Name(["none"]),
                                              docstring="No Interrupt")
        plic_mapping.add_entry(none_irq_id, unknown_source)

        # When we generate the `interrupts` enum, the only info we have about
        # the source is the module name. We'll use `source_name_map` to map a
        # short module name to the full name object used for the enum constant.
        source_name_map = {}

        for name in self.top["interrupt_module"]:
            source_name = sources.add_constant(Name.from_snake_case(name),
                                               docstring=name)
            source_name_map[name] = source_name

        sources.add_last_constant("Final PLIC peripheral")

        for intr in self.top["interrupt"]:
            # Some interrupts are multiple bits wide. Here we deal with that by
            # adding a bit-index suffix
            if "width" in intr and int(intr["width"]) != 1:
                for i in range(int(intr["width"])):
                    name = Name.from_snake_case(intr["name"]) + Name([str(i)])
                    irq_id = interrupts.add_constant(name,
                                                     docstring="{} {}".format(
                                                         intr["name"], i))
                    source_name = source_name_map[intr["module_name"]]
                    plic_mapping.add_entry(irq_id, source_name)
            else:
                name = Name.from_snake_case(intr["name"])
                irq_id = interrupts.add_constant(name, docstring=intr["name"])
                source_name = source_name_map[intr["module_name"]]
                plic_mapping.add_entry(irq_id, source_name)

        interrupts.add_last_constant("The Last Valid Interrupt ID.")

        self.plic_sources = sources
        self.plic_interrupts = interrupts
        self.plic_mapping = plic_mapping

    def _init_alert_mapping(self):
        """We eventually want to generate a mapping from alert id to the source
        peripheral.

        In order to do so, we generate two enums (one for alerts, one for
        sources), and store the generated names in a dictionary that represents
        the mapping.

        Alert Handler has no concept of "no alert", unlike the PLIC.

        The alerts have to be added in order, to ensure that they get the
        correct mapping to their alert id, which is used for addressing the
        right registers and bits.
        """
        sources = CEnum(self._top_name + Name(["alert", "peripheral"]))
        alerts = CEnum(self._top_name + Name(["alert", "id"]))
        alert_mapping = CArrayMapping(
            self._top_name + Name(["alert", "for", "peripheral"]),
            sources.name)

        # When we generate the `alerts` enum, the only info we have about the
        # source is the module name. We'll use `source_name_map` to map a short
        # module name to the full name object used for the enum constant.
        source_name_map = {}

        for name in self.top["alert_module"]:
            source_name = sources.add_constant(Name.from_snake_case(name),
                                               docstring=name)
            source_name_map[name] = source_name

        sources.add_last_constant("Final Alert peripheral")

        for alert in self.top["alert"]:
            if "width" in alert and int(alert["width"]) != 1:
                for i in range(int(alert["width"])):
                    name = Name.from_snake_case(alert["name"]) + Name([str(i)])
                    irq_id = alerts.add_constant(name,
                                                 docstring="{} {}".format(
                                                     alert["name"], i))
                    source_name = source_name_map[alert["module_name"]]
                    alert_mapping.add_entry(irq_id, source_name)
            else:
                name = Name.from_snake_case(alert["name"])
                alert_id = alerts.add_constant(name, docstring=alert["name"])
                source_name = source_name_map[alert["module_name"]]
                alert_mapping.add_entry(alert_id, source_name)

        alerts.add_last_constant("The Last Valid Alert ID.")

        self.alert_sources = sources
        self.alert_alerts = alerts
        self.alert_mapping = alert_mapping

    def _init_pinmux_mapping(self):
        """Generate C enums for addressing pinmux registers and in/out selects.

        Inputs are connected in order: inouts, then inputs
        Outputs are connected in order: inouts, then outputs

        Inputs:
        - Peripheral chooses register field (pinmux_peripheral_in)
        - Insel chooses MIO input (pinmux_insel)

        Outputs:
        - MIO chooses register field (pinmux_mio_out)
        - Outsel chooses peripheral output (pinmux_outsel)

        Insel and outsel have some special values which are captured here too.
        """
        pinmux_info = self.top["pinmux"]

        # Peripheral Inputs
        peripheral_in = CEnum(self._top_name +
                              Name(["pinmux", "peripheral", "in"]))
        for signal in pinmux_info["inouts"] + pinmux_info["inputs"]:
            if "width" in signal and int(signal["width"]) != 1:
                for i in range(int(signal["width"])):
                    name = Name.from_snake_case(signal["name"]) + Name(
                        [str(i)])
                    peripheral_in.add_constant(name,
                                               docstring="{} {}".format(
                                                   signal["name"], i))
            else:
                peripheral_in.add_constant(Name.from_snake_case(
                    signal["name"]),
                                           docstring=signal["name"])
        peripheral_in.add_last_constant("Last valid peripheral input")

        # Pinmux Input Selects
        insel = CEnum(self._top_name + Name(["pinmux", "insel"]))
        insel.add_constant(Name(["constant", "zero"]),
                           docstring="Tie constantly to zero")
        insel.add_constant(Name(["constant", "one"]),
                           docstring="Tie constantly to one")
        for i in range(int(pinmux_info["num_mio"])):
            insel.add_constant(Name(["mio", str(i)]),
                               docstring="MIO Pad {}".format(i))
        insel.add_last_constant("Last valid insel value")

        # MIO Outputs
        mio_out = CEnum(self._top_name + Name(["pinmux", "mio", "out"]))
        for i in range(int(pinmux_info["num_mio"])):
            mio_out.add_constant(Name([str(i)]),
                                 docstring="MIO Pad {}".format(i))
        mio_out.add_last_constant("Last valid mio output")

        # Pinmux Output Selects
        outsel = CEnum(self._top_name + Name(["pinmux", "outsel"]))
        outsel.add_constant(Name(["constant", "zero"]),
                            docstring="Tie constantly to zero")
        outsel.add_constant(Name(["constant", "one"]),
                            docstring="Tie constantly to one")
        outsel.add_constant(Name(["constant", "high", "z"]),
                            docstring="Tie constantly to high-Z")
        for signal in pinmux_info["inouts"] + pinmux_info["outputs"]:
            if "width" in signal and int(signal["width"]) != 1:
                for i in range(int(signal["width"])):
                    name = Name.from_snake_case(signal["name"]) + Name(
                        [str(i)])
                    outsel.add_constant(name,
                                        docstring="{} {}".format(
                                            signal["name"], i))
            else:
                outsel.add_constant(Name.from_snake_case(signal["name"]),
                                    docstring=signal["name"])
        outsel.add_last_constant("Last valid outsel value")

        self.pinmux_peripheral_in = peripheral_in
        self.pinmux_insel = insel
        self.pinmux_mio_out = mio_out
        self.pinmux_outsel = outsel

    def _init_pwrmgr_wakeups(self):
        enum = CEnum(self._top_name +
                     Name(["power", "manager", "wake", "ups"]))

        for signal in self.top["wakeups"]:
            enum.add_constant(
                Name.from_snake_case(signal["module"]) +
                Name.from_snake_case(signal["name"]))

        enum.add_last_constant("Last valid pwrmgr wakeup signal")

        self.pwrmgr_wakeups = enum

    # Enumerates the positions of all software controllable resets
    def _init_rstmgr_sw_rsts(self):
        sw_rsts = [
            rst for rst in self.top["resets"]["nodes"]
            if 'sw' in rst and rst['sw'] == 1
        ]

        enum = CEnum(self._top_name +
                     Name(["reset", "manager", "sw", "resets"]))

        for rst in sw_rsts:
            enum.add_constant(Name.from_snake_case(rst["name"]))

        enum.add_last_constant("Last valid rstmgr software reset request")

        self.rstmgr_sw_rsts = enum

    def _init_pwrmgr_reset_requests(self):
        enum = CEnum(self._top_name +
                     Name(["power", "manager", "reset", "requests"]))

        for signal in self.top["reset_requests"]:
            enum.add_constant(
                Name.from_snake_case(signal["module"]) +
                Name.from_snake_case(signal["name"]))

        enum.add_last_constant("Last valid pwrmgr reset_request signal")

        self.pwrmgr_reset_requests = enum

    def _init_clkmgr_clocks(self):
        """
        Creates CEnums for accessing the software-controlled clocks in the
        design.

        The logic here matches the logic in topgen.py in how it instantiates the
        clock manager with the described clocks.

        We differentiate "gateable" clocks and "hintable" clocks because the
        clock manager has separate register interfaces for each group.
        """

        aon_clocks = set()
        for src in self.top['clocks']['srcs'] + self.top['clocks'][
                'derived_srcs']:
            if src['aon'] == 'yes':
                aon_clocks.add(src['name'])

        gateable_clocks = CEnum(self._top_name + Name(["gateable", "clocks"]))
        hintable_clocks = CEnum(self._top_name + Name(["hintable", "clocks"]))

        # This replicates the behaviour in `topgen.py` in deriving `hints` and
        # `sw_clocks`.
        for group in self.top['clocks']['groups']:
            for (name, source) in group['clocks'].items():
                if source not in aon_clocks:
                    # All these clocks start with `clk_` which is redundant.
                    clock_name = Name.from_snake_case(name).remove_part("clk")
                    docstring = "Clock {} in group {}".format(
                        name, group['name'])
                    if group["sw_cg"] == "yes":
                        gateable_clocks.add_constant(clock_name, docstring)
                    elif group["sw_cg"] == "hint":
                        hintable_clocks.add_constant(clock_name, docstring)

        gateable_clocks.add_last_constant("Last Valid Gateable Clock")
        hintable_clocks.add_last_constant("Last Valid Hintable Clock")

        self.clkmgr_gateable_clocks = gateable_clocks
        self.clkmgr_hintable_clocks = hintable_clocks
