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

'''Code representing an IP block for reggen'''

from typing import Dict, List, Optional, Sequence, Set, Tuple

import hjson  # type: ignore

from reggen.alert import Alert
from reggen.bus_interfaces import BusInterfaces
from reggen.clocking import Clocking, ClockingItem
from reggen.inter_signal import InterSignal
from reggen.lib import (check_keys, check_name, check_int, check_bool, check_list)
from reggen.params import ReggenParams, LocalParam
from reggen.reg_block import RegBlock
from reggen.signal import Signal
from reggen.countermeasure import CounterMeasure


REQUIRED_ALIAS_FIELDS = {
    'alias_impl': [
        's',
        "identifier for this alias implementation"
    ],
    'alias_target': [
        's',
        "name of the component to apply the alias file to"
    ],
    'registers': [
        'l',
        "list of alias register definition groups"
    ],
    'bus_interfaces': [
        'l',
        "bus interfaces for the device"
    ],
}

# TODO: we may want to support for countermeasure and parameter aliases
# in the future.
OPTIONAL_ALIAS_FIELDS: Dict[str, List[str]] = {
}

REQUIRED_FIELDS = {
    'name': ['s', "name of the component"],
    'clocking': ['l', "clocking for the device"],
    'bus_interfaces': ['l', "bus interfaces for the device"],
    'registers': [
        'l',
        "list of register definition groups and "
        "offset control groups"
    ]
}

OPTIONAL_FIELDS = {
    'alert_list': ['lnw', "list of peripheral alerts"],
    'available_inout_list': ['lnw', "list of available peripheral inouts"],
    'available_input_list': ['lnw', "list of available peripheral inputs"],
    'available_output_list': ['lnw', "list of available peripheral outputs"],
    'expose_reg_if': ['pb', 'if set, expose reg interface in reg2hw signal'],
    'interrupt_list': ['lnw', "list of peripheral interrupts"],
    'inter_signal_list': ['l', "list of inter-module signals"],
    'no_auto_alert_regs': [
        's', "Set to true to suppress automatic "
        "generation of alert test registers. "
        "Defaults to true if no alert_list is present. "
        "Otherwise this defaults to false. "
    ],
    'no_auto_intr_regs': [
        's', "Set to true to suppress automatic "
        "generation of interrupt registers. "
        "Defaults to true if no interrupt_list is present. "
        "Otherwise this defaults to false. "
    ],
    'param_list': ['lp', "list of parameters of the IP"],
    'regwidth': ['d', "width of registers in bits (default 32)"],
    'reset_request_list': ['l', 'list of signals requesting reset'],
    'scan': ['pb', 'Indicates the module have `scanmode_i`'],
    'scan_reset': ['pb', 'Indicates the module have `scan_rst_ni`'],
    'scan_en': ['pb', 'Indicates the module has `scan_en_i`'],
    'SPDX-License-Identifier': [
        's', "License ientifier (if using pure json) "
        "Only use this if unable to put this "
        "information in a comment at the top of the "
        "file."
    ],
    'wakeup_list': ['lnw', "list of peripheral wakeups"],
    'countermeasures': ["ln", "list of countermeasures in this block"]
}


class IpBlock:
    def __init__(self,
                 name: str,
                 regwidth: int,
                 params: ReggenParams,
                 reg_blocks: Dict[Optional[str], RegBlock],
                 alias_impl: Optional[str],
                 interrupts: Sequence[Signal],
                 no_auto_intr: bool,
                 alerts: List[Alert],
                 no_auto_alert: bool,
                 scan: bool,
                 inter_signals: List[InterSignal],
                 bus_interfaces: BusInterfaces,
                 clocking: Clocking,
                 xputs: Tuple[Sequence[Signal],
                              Sequence[Signal],
                              Sequence[Signal]],
                 wakeups: Sequence[Signal],
                 reset_requests: Sequence[Signal],
                 expose_reg_if: bool,
                 scan_reset: bool,
                 scan_en: bool,
                 countermeasures: List[CounterMeasure]):
        assert reg_blocks

        # Check that register blocks are in bijection with device interfaces
        reg_block_names = reg_blocks.keys()
        dev_if_names = []  # type: List[Optional[str]]
        dev_if_names += bus_interfaces.named_devices
        if bus_interfaces.has_unnamed_device:
            dev_if_names.append(None)
        assert set(reg_block_names) == set(dev_if_names)

        self.name = name
        self.regwidth = regwidth
        self.reg_blocks = reg_blocks
        self.alias_impl = alias_impl
        self.params = params
        self.interrupts = interrupts
        self.no_auto_intr = no_auto_intr
        self.alerts = alerts
        self.no_auto_alert = no_auto_alert
        self.scan = scan
        self.inter_signals = inter_signals
        self.bus_interfaces = bus_interfaces
        self.clocking = clocking
        self.xputs = xputs
        self.wakeups = wakeups
        self.reset_requests = reset_requests
        self.expose_reg_if = expose_reg_if
        self.scan_reset = scan_reset
        self.scan_en = scan_en
        self.countermeasures = countermeasures

    @staticmethod
    def from_raw(param_defaults: List[Tuple[str, str]],
                 raw: object,
                 where: str) -> 'IpBlock':

        rd = check_keys(raw, 'block at ' + where,
                        list(REQUIRED_FIELDS.keys()),
                        list(OPTIONAL_FIELDS.keys()))

        name = check_name(rd['name'], 'name of block at ' + where)

        what = '{} block at {}'.format(name, where)

        r_regwidth = rd.get('regwidth')
        if r_regwidth is None:
            regwidth = 32
        else:
            regwidth = check_int(r_regwidth, 'regwidth field of ' + what)
            if regwidth <= 0:
                raise ValueError('Invalid regwidth field for {}: '
                                 '{} is not positive.'
                                 .format(what, regwidth))

        params = ReggenParams.from_raw('parameter list for ' + what,
                                       rd.get('param_list', []))
        try:
            params.apply_defaults(param_defaults)
        except (ValueError, KeyError) as err:
            raise ValueError('Failed to apply defaults to params: {}'
                             .format(err)) from None

        init_block = RegBlock(regwidth, params)

        interrupts = Signal.from_raw_list('interrupt_list for block {}'
                                          .format(name),
                                          rd.get('interrupt_list', []))
        alerts = Alert.from_raw_list('alert_list for block {}'
                                     .format(name),
                                     rd.get('alert_list', []))
        known_cms = {}
        raw_cms = rd.get('countermeasures', [])

        countermeasures = CounterMeasure.from_raw_list(
            'countermeasure list for block {}'
            .format(name), raw_cms)

        # Ensure that the countermeasures are unique
        for x in countermeasures:
            if str(x) in known_cms:
                raise RuntimeError(f"Duplicate countermeasure {str(x)}")
            else:
                known_cms.update({str(x): 1})

        no_auto_intr = check_bool(rd.get('no_auto_intr_regs', not interrupts),
                                  'no_auto_intr_regs field of ' + what)

        no_auto_alert = check_bool(rd.get('no_auto_alert_regs', not alerts),
                                   'no_auto_alert_regs field of ' + what)

        if interrupts and not no_auto_intr:
            if interrupts[-1].bits.msb >= regwidth:
                raise ValueError("Interrupt list for {} is too wide: "
                                 "msb is {}, which doesn't fit with a "
                                 "regwidth of {}."
                                 .format(what,
                                         interrupts[-1].bits.msb, regwidth))
            init_block.make_intr_regs(interrupts)

        if alerts:
            if not no_auto_alert:
                if len(alerts) > regwidth:
                    raise ValueError("Interrupt list for {} is too wide: "
                                     "{} alerts don't fit with a regwidth of {}."
                                     .format(what, len(alerts), regwidth))
                init_block.make_alert_regs(alerts)

            # Generate a NumAlerts parameter
            existing_param = params.get('NumAlerts')
            if existing_param is not None:
                if ((not isinstance(existing_param, LocalParam) or
                     existing_param.param_type != 'int' or
                     existing_param.value != str(len(alerts)))):
                    raise ValueError('Conflicting definition of NumAlerts '
                                     'parameter.')
            else:
                params.add(LocalParam(name='NumAlerts',
                                      desc='Number of alerts',
                                      param_type='int',
                                      value=str(len(alerts))))

        scan = check_bool(rd.get('scan', False), 'scan field of ' + what)

        r_inter_signals = check_list(rd.get('inter_signal_list', []),
                                     'inter_signal_list field')
        inter_signals = [
            InterSignal.from_raw('entry {} of the inter_signal_list field'
                                 .format(idx + 1),
                                 entry)
            for idx, entry in enumerate(r_inter_signals)
        ]

        bus_interfaces = (BusInterfaces.
                          from_raw(rd['bus_interfaces'],
                                   'bus_interfaces field of ' + where))
        inter_signals += bus_interfaces.inter_signals()

        clocking = Clocking.from_raw(rd['clocking'],
                                     'clocking field of ' + what)

        reg_blocks = RegBlock.build_blocks(init_block, rd['registers'],
                                           bus_interfaces,
                                           clocking, False)

        xputs = (
            Signal.from_raw_list('available_inout_list for block ' + name,
                                 rd.get('available_inout_list', [])),
            Signal.from_raw_list('available_input_list for block ' + name,
                                 rd.get('available_input_list', [])),
            Signal.from_raw_list('available_output_list for block ' + name,
                                 rd.get('available_output_list', []))
        )
        wakeups = Signal.from_raw_list('wakeup_list for block ' + name,
                                       rd.get('wakeup_list', []))
        rst_reqs = Signal.from_raw_list('reset_request_list for block ' + name,
                                        rd.get('reset_request_list', []))

        expose_reg_if = check_bool(rd.get('expose_reg_if', False),
                                   'expose_reg_if field of ' + what)

        scan_reset = check_bool(rd.get('scan_reset', False),
                                'scan_reset field of ' + what)

        scan_en = check_bool(rd.get('scan_en', False),
                             'scan_en field of ' + what)

        # Check that register blocks are in bijection with device interfaces
        reg_block_names = reg_blocks.keys()
        dev_if_names = []  # type: List[Optional[str]]
        dev_if_names += bus_interfaces.named_devices
        if bus_interfaces.has_unnamed_device:
            dev_if_names.append(None)
        if set(reg_block_names) != set(dev_if_names):
            raise ValueError("IP block {} defines device interfaces, named {} "
                             "but its registers don't match (they are keyed "
                             "by {})."
                             .format(name, dev_if_names,
                                     list(reg_block_names)))

        return IpBlock(name, regwidth, params, reg_blocks, None,
                       interrupts, no_auto_intr, alerts, no_auto_alert,
                       scan, inter_signals, bus_interfaces, clocking, xputs,
                       wakeups, rst_reqs, expose_reg_if, scan_reset, scan_en,
                       countermeasures)

    @staticmethod
    def from_text(txt: str,
                  param_defaults: List[Tuple[str, str]],
                  where: str) -> 'IpBlock':
        '''Load an IpBlock from an hjson description in txt'''
        return IpBlock.from_raw(param_defaults,
                                hjson.loads(txt, use_decimal=True),
                                where)

    @staticmethod
    def from_path(path: str,
                  param_defaults: List[Tuple[str, str]]) -> 'IpBlock':
        '''Load an IpBlock from an hjson description in a file at path'''
        with open(path, 'r', encoding='utf-8') as handle:
            return IpBlock.from_text(handle.read(), param_defaults,
                                     'file at {!r}'.format(path))

    def alias_from_raw(self,
                       scrub: bool,
                       raw: object,
                       where: str) -> None:
        '''Parses and validates an alias reg block and adds it to this IpBlock.

        The alias register definitions are compared with the corresponding
        generic register definitions in self.reg_blocks to ensure that the
        register and field structure is the same. Only a subset of register
        and field attributes may differ and all other attributes must be
        identical. The overridable attributes are defined in register.py and
        field.py, but typically comprise attributes like 'name', 'desc',
        'resval' and 'tags'.

        The alias register information is then applied to the self.reg_blocks
        datastructure. Generic register descriptions with no associated alias
        register definition just remain unmodified, meaning that the user can
        choose to only provide alias overrides for a subset of all registers.
        The resulting "augmented" register block is therefore always guaranteed
        to be structurally identical to the unmodified generic register block.

        Note that the alias register definition also overrides the hier_path
        variable associated with the corresponding bus interfaces.

        Setting the scrub argument to True will scrub sensitive fields in the
        alias definition and replace the entire register block of the target
        interface with the scrubbed alias reg block. This is helpful to create
        the generic CSR structure matching the alias definition automatically.
        '''
        rd = check_keys(raw, 'block at ' + where,
                        list(REQUIRED_ALIAS_FIELDS.keys()),
                        list(OPTIONAL_ALIAS_FIELDS.keys()))

        alias_bus_interfaces = (BusInterfaces.
                                from_raw(rd['bus_interfaces'],
                                         'bus_interfaces of block at ' + where))
        if ((alias_bus_interfaces.has_unnamed_host or
             alias_bus_interfaces.named_hosts)):
            raise ValueError("Alias registers cannot be defined for host "
                             "interfaces (in block at {})."
                             .format(where))
        # Alias register definitions are only compatible with named devices.
        if ((alias_bus_interfaces.has_unnamed_device or
             self.bus_interfaces.has_unnamed_device)):
            raise ValueError("Alias registers must use named devices "
                             "(in block at {}).".format(where))

        # Check that the device interface names are
        # a subset of the already defined register blocks
        bus_device_names = set(self.bus_interfaces.named_devices)
        alias_bus_device_names = set(alias_bus_interfaces.named_devices)
        if not alias_bus_device_names.issubset(bus_device_names):
            raise ValueError("Alias file {} refers to device names {} that "
                             "do not map to device names in {}."
                             .format(where, list(alias_bus_device_names),
                                     self.name))

        self.alias_impl = check_name(rd['alias_impl'],
                                     'alias_impl of block at ' + where)

        alias_target = check_name(rd['alias_target'],
                                  'alias_target of block at ' + where)

        if alias_target != self.name:
            raise ValueError("Alias target block name {} in {} "
                             "does not match block name {}."
                             .format(alias_target, where, self.name))

        init_block = RegBlock(self.regwidth, self.params)

        alias_reg_blocks = RegBlock.build_blocks(init_block, rd['registers'],
                                                 self.bus_interfaces,
                                                 self.clocking,
                                                 True)

        # Check that alias register block names are
        # a subset of the already defined register blocks
        alias_reg_block_names = set(alias_reg_blocks.keys())

        if not alias_reg_block_names.issubset(set(self.reg_blocks.keys())):
            raise ValueError("Alias file {} refers to register blocks {} that "
                             "do not map to register blocks in {}."
                             .format(where, list(alias_reg_block_names),
                                     self.name))

        # Check that the alias bus interface names and register blocks match
        if alias_reg_block_names != alias_bus_device_names:
            raise ValueError("Interface and register block names do not match "
                             "in {}.".format(where))

        # Validate alias registers against the generic reg blocks,
        # and enhance the information in the existing datastructures.
        for block_key, alias_block in alias_reg_blocks.items():
            # Double check the interface definition options
            if self.bus_interfaces.device_async:
                if not alias_bus_interfaces.device_async:
                    raise ValueError('Missing device_async key in alias '
                                     'interface {} in {}'
                                     .format(block_key, where))
                if ((alias_bus_interfaces.device_async[block_key] !=
                     self.bus_interfaces.device_async[block_key])):
                    raise ValueError('Inconsistent configuration of interface '
                                     '{} in {}'
                                     .format(block_key, where))

            if scrub:
                # scrub alias definitions and replace the entire block.
                alias_block.scrub_alias(where)
                self.reg_blocks[block_key] = alias_block
            else:
                # Override hier path of aliased interface
                hier_path = alias_bus_interfaces.device_hier_paths[block_key]
                self.bus_interfaces.device_hier_paths[block_key] = hier_path

                # Validate and apply alias definitions
                self.reg_blocks[block_key].apply_alias(alias_block, where)

    def alias_from_text(self,
                        scrub: bool,
                        txt: str,
                        where: str) -> None:
        '''Load alias regblocks from an hjson description in txt'''
        self.alias_from_raw(scrub, hjson.loads(txt, use_decimal=True), where)

    def alias_from_path(self,
                        scrub: bool,
                        path: str) -> None:
        '''Load alias regblocks from an hjson description in a file at path'''
        with open(path, 'r', encoding='utf-8') as handle:
            self.alias_from_text(scrub,
                                 handle.read(),
                                 'alias file at {!r}'.format(path))

    def _asdict(self) -> Dict[str, object]:
        ret = {
            'name': self.name,
            'regwidth': self.regwidth
        }
        if len(self.reg_blocks) == 1 and None in self.reg_blocks:
            ret['registers'] = self.reg_blocks[None].as_dicts()
        else:
            ret['registers'] = {k: v.as_dicts()
                                for k, v in self.reg_blocks.items()}

        ret['param_list'] = self.params.as_dicts()
        ret['interrupt_list'] = self.interrupts
        ret['no_auto_intr_regs'] = self.no_auto_intr
        ret['alert_list'] = self.alerts
        ret['no_auto_alert_regs'] = self.no_auto_alert
        ret['scan'] = self.scan
        ret['inter_signal_list'] = self.inter_signals
        ret['bus_interfaces'] = self.bus_interfaces.as_dicts()

        ret['clocking'] = self.clocking.items

        inouts, inputs, outputs = self.xputs
        if inouts:
            ret['available_inout_list'] = inouts
        if inputs:
            ret['available_input_list'] = inputs
        if outputs:
            ret['available_output_list'] = outputs

        if self.wakeups:
            ret['wakeup_list'] = self.wakeups
        if self.reset_requests:
            ret['reset_request_list'] = self.reset_requests

        ret['scan_reset'] = self.scan_reset
        ret['scan_en'] = self.scan_en

        return ret

    def get_rnames(self) -> Set[str]:
        ret = set()  # type: Set[str]
        for rb in self.reg_blocks.values():
            ret = ret.union(set(rb.name_to_offset.keys()))
        return ret

    def get_signals_as_list_of_dicts(self) -> List[Dict[str, object]]:
        '''Look up and return signal by name'''
        result = []
        for iodir, xput in zip(('inout', 'input', 'output'), self.xputs):
            for sig in xput:
                result.append(sig.as_nwt_dict(iodir))
        return result

    def get_signal_by_name_as_dict(self, name: str) -> Dict[str, object]:
        '''Look up and return signal by name'''
        sig_list = self.get_signals_as_list_of_dicts()
        for sig in sig_list:
            if sig['name'] == name:
                return sig
        else:
            raise ValueError("Signal {} does not exist in IP block {}"
                             .format(name, self.name))

    def has_shadowed_reg(self) -> bool:
        '''Return boolean indication whether reg block contains shadowed registers'''

        for rb in self.reg_blocks.values():
            if rb.has_shadowed_reg():
                return True

        # if we are here, then no one has has a shadowed register
        return False

    def get_primary_clock(self) -> ClockingItem:
        '''Return primary clock of an block'''

        return self.clocking.primary

    def check_cm_annotations(self,
                             rtl_names: Dict[str, List[Tuple[str, int]]],
                             where: str) -> None:
        '''Check RTL annotations against countermeasure list of this block'''

        what = '{} block at {}'.format(self.name, where)
        CounterMeasure.check_annotation_list(what,
                                             rtl_names,
                                             self.countermeasures)
