# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

from collections import OrderedDict
from pathlib import Path
from typing import List
import hjson

# This file is $REPO_TOP/util/make_new_dif/ip.py, so it takes three parent()
# calls to get back to the top.
REPO_TOP = Path(__file__).resolve().parent.parent.parent


class Alert:
    """Holds alert information for populating DIF code templates.

    Attributes:
        name_snake (str): Alert short name in lower snake case.
        name_upper (str): Alert short name in upper snake case.
        name_camel (str): Alert short name in camel case.
        description (str): Full description of the alert.

    """
    def __init__(self, alert: OrderedDict) -> None:
        self.name_snake = alert["name"]
        self.name_upper = self.name_snake.upper()
        self.name_camel = "".join(
            [word.capitalize() for word in self.name_snake.split("_")])
        _multiline_description = alert["desc"][0].upper() + alert["desc"][1:]
        self.description = _multiline_description.replace("\n", " ")


class Irq:
    """Holds IRQ information for populating DIF code templates.

    Attributes:
        name_snake (str): IRQ short name in lower snake case.
        name_upper (str): IRQ short name in upper snake case.
        name_camel (str): IRQ short name in camel case.
        description (str): full description of the IRQ.

    """
    def __init__(self, irq: OrderedDict) -> None:
        self.name_snake = irq["name"]
        self.name_upper = self.name_snake.upper()
        self.name_camel = "".join(
            [word.capitalize() for word in self.name_snake.split("_")])
        _multiline_description = irq["desc"][0].upper() + irq["desc"][1:]
        self.description = _multiline_description.replace("\n", " ")
        self.width = irq["width"] if "width" in irq else 1


class Parameter:
    """Holds IP Parameter information for populating DIF code templates.

    Attributes:
        name (str): Parameter name.
        description (str): Parameter description.
        default (int): Default parameter value.

    """
    def __init__(self, parameter: OrderedDict) -> None:
        self.name = parameter["name"]
        self.description = parameter["desc"]
        self.default = None
        if "default" in parameter:
            self.default = parameter["default"]


class Ip:
    """Holds all IP metadata mined from an IP's name and HJSON file.

    Attributes:
        name_snake (str): IP short name in lower snake case.
        name_upper (str): IP short name in upper snake case.
        name_camel (str): IP short name in camel case.
        name_long_lower (str): IP full name in lower case.
        name_long_upper (str): IP full name with first letter capitalized.
        alerts (List[alerts]): List of Alert objs constructed from HSJON data.
        irqs (List[Irq]): List of Irq objs constructed from HJSON data.

    """
    def __init__(self, name_snake: str, name_long_lower: str,
                 templated_modules: List[str], ipgen_modules: List[str]) -> None:
        """Mines metadata to populate this Ip object.

        Args:
            name_snake: IP short name in lower snake case (e.g., pwrmgr).
            name_long_lower: IP full name in lower case (e.g., power manager).
            templated_modules: Templated modules where hjson is under top_*
            ipgen_modules: Ipgen modules where hjson is under ip_autogen
        """
        # Generate various IP name formats.
        self.name_snake = name_snake
        self.name_upper = self.name_snake.upper()
        self.name_camel = "".join(
            [word.capitalize() for word in self.name_snake.split("_")])
        self.name_long_lower = name_long_lower
        # We just want to set the first character to title case. In particular,
        # .capitalize() does not do the right thing, since it would convert
        # UART to Uart.
        self.name_long_upper = (self.name_long_lower[0].upper() +
                                self.name_long_lower[1:])
        # Load HJSON data.
        if self.name_snake in ipgen_modules:
            data_dir = REPO_TOP / "hw/top_earlgrey/ip_autogen/{0}/data".format(
                self.name_snake)
        elif self.name_snake in templated_modules:
            data_dir = REPO_TOP / "hw/top_earlgrey/ip/{0}/data/autogen".format(
                self.name_snake)
        else:
            data_dir = REPO_TOP / "hw/ip/{0}/data".format(self.name_snake)
        _hjson_file = data_dir / "{0}.hjson".format(self.name_snake)
        with _hjson_file.open("r") as f:
            _hjson_str = f.read()
        self._hjson_data = hjson.loads(_hjson_str)
        # Load Alert data from HJSON.
        self.alerts = self._load_alerts()
        # Load IRQ data from HJSON.
        self.irqs = self._load_irqs()
        # Load Parameters from HJSON
        self.parameters = self._load_parameters()

    def _load_alerts(self):
        assert (self._hjson_data and
                "ERROR: must load IP HJSON before loading Alerts")
        alerts = []
        if "alert_list" in self._hjson_data:
            for alert in self._hjson_data["alert_list"]:
                alerts.append(Alert(alert))
        return alerts

    def _load_irqs(self):
        assert (self._hjson_data and
                "ERROR: must load IP HJSON before loading IRQs")
        irqs = []
        if "interrupt_list" in self._hjson_data:
            for irq in self._hjson_data["interrupt_list"]:
                irqs.append(Irq(irq))
        return irqs

    def _load_parameters(self):
        assert (self._hjson_data and
                "ERROR: must load IP HJSON before loarding Parameters")
        parameters = {}
        if "param_list" in self._hjson_data:
            for parameter in self._hjson_data["param_list"]:
                p = Parameter(parameter)
                parameters[p.name] = p
        return parameters
