# 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 level SW tests.

We maintain as a separate class rather than merge implementation with c.py,
because both serve different purposes and need to capture the information
differently.
"""

import logging as log
import sys
from typing import Dict

from reggen.ip_block import IpBlock

from .c import TopGenC
from .lib import Name


class TestPeripheral:
    """Captures a peripheral instance's attributes for use in SW tests.

    It encapsulates the settings for each peripheral's instance in the design.
    These settings are captured as identifiers that are already defined in
    other autogenerated / hand-edited sources such as top_{name}.h and the DIF
    headers, rather than hard-coded constants. This is done to ensure that a
    single source of truth is referenced in all of the tests.
    """
    def __init__(self, name: str, inst_name: str, base_addr_name: str,
                 is_templated: bool):
        self.name = name
        self.inst_name = inst_name
        self.base_addr_name = base_addr_name
        self.is_templated = is_templated


class IrqTestPeripheral(TestPeripheral):
    """Captures a peripheral instance's attributes for use in IRQ test."""
    def __init__(self, name: str, inst_name: str, base_addr_name: str,
                 is_templated: bool, plic_name: str, start_irq: str,
                 end_irq: str, plic_start_irq: str):
        super().__init__(name, inst_name, base_addr_name, is_templated)
        self.plic_name = plic_name
        self.start_irq = start_irq
        self.end_irq = end_irq
        self.plic_start_irq = plic_start_irq


class TopGenCTest(TopGenC):
    def __init__(self, top_info, name_to_block: Dict[str, IpBlock]):
        super().__init__(top_info, name_to_block)

        self.irq_peripherals = self._get_irq_peripherals()

    def _get_irq_peripherals(self):
        irq_peripherals = []
        self.devices()
        for entry in self.top['module']:
            inst_name = entry['name']
            if inst_name not in self.top["interrupt_module"]:
                continue

            name = entry['type']
            plic_name = (self._top_name + Name(["plic", "peripheral"]) +
                         Name.from_snake_case(inst_name))
            plic_name = plic_name.as_c_enum()

            # Device regions may have multiple TL interfaces. Pick the region
            # associated with the 'core' interface.
            if_name = None if len(
                self.device_regions[inst_name]) == 1 else 'core'
            try:
                region = self.device_regions[inst_name][if_name]
            except KeyError:
                log.error(f"The 'base_addrs' dict for {name} needs to have "
                          "one entry keyed with 'None' or 'core'.")
                sys.exit(1)

            base_addr_name = region.base_addr_name().as_c_define()
            is_templated = 'attr' in entry and entry['attr'] == 'templated'

            plic_name = (self._top_name + Name(["plic", "peripheral"]) +
                         Name.from_snake_case(inst_name))
            plic_name = plic_name.as_c_enum()

            start_irq = self.device_irqs[inst_name][0]
            end_irq = self.device_irqs[inst_name][-1]
            plic_start_irq = (self._top_name + Name(["plic", "irq", "id"]) +
                              Name.from_snake_case(start_irq))
            plic_start_irq = plic_start_irq.as_c_enum()

            # Get DIF compliant, instance-agnostic IRQ names.
            start_irq = start_irq.replace(inst_name, f"dif_{name}_irq", 1)
            start_irq = Name.from_snake_case(start_irq).as_c_enum()
            end_irq = end_irq.replace(inst_name, f"dif_{name}_irq", 1)
            end_irq = Name.from_snake_case(end_irq).as_c_enum()

            irq_peripheral = IrqTestPeripheral(name, inst_name, base_addr_name,
                                               is_templated, plic_name, start_irq,
                                               end_irq, plic_start_irq)
            irq_peripherals.append(irq_peripheral)

        irq_peripherals.sort(key=lambda p: p.inst_name)
        return irq_peripherals
