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

from typing import Dict, List, Optional

from design.mubi import prim_mubi # type: ignore

from reggen.access import SWAccess, HWAccess
from reggen.bits import Bits
from reggen.enum_entry import EnumEntry
from reggen.lib import (check_keys, check_str, check_name, check_bool,
                        check_list, check_str_list, check_xint)
from reggen.params import ReggenParams

REQUIRED_FIELDS = {
    'bits': ['b', "bit or bit range (msb:lsb)"]
}

OPTIONAL_FIELDS = {
    'name': ['s', "name of the field"],
    'desc': [
        't',
        "description of field (required if the field has a name). "
        "This field supports the markdown syntax."
    ],
    'alias_target': [
        's',
        "name of the field to apply the alias definition to."
    ],
    'swaccess': [
        's', "software access permission, copied from "
        "register if not provided in field. "
        "(Tool adds if not provided.)"
    ],
    'hwaccess': [
        's', "hardware access permission, copied from "
        "register if not prvided in field. "
        "(Tool adds if not provided.)"
    ],
    'hwqe': [
        'b', "'true' if hardware uses 'q' enable signal, "
        "which is latched signal of software write pulse. "
        "Copied from register if not provided in field. "
        "(Tool adds if not provided.)"
    ],
    'resval': [
        'x', "reset value, comes from register resval "
        "if not provided in field. Zero if neither "
        "are provided and the field is readable, "
        "x if neither are provided and the field "
        "is wo. Must match if both are provided."
    ],
    'enum': ['l', "list of permitted enumeration groups"],
    'tags': [
        's',
        "tags for the field, followed by the format 'tag_name:item1:item2...'"
    ],
    'mubi': [
        'b',
        "boolean flag for whether the field is a multi-bit type"
    ]
}


class Field:
    def __init__(self,
                 name: str,
                 alias_target: Optional[str],
                 desc: Optional[str],
                 tags: List[str],
                 swaccess: SWAccess,
                 hwaccess: HWAccess,
                 hwqe: bool,
                 bits: Bits,
                 resval: Optional[int],
                 enum: Optional[List[EnumEntry]],
                 mubi: bool):
        self.name = name
        self.alias_target = alias_target
        self.desc = desc
        self.tags = tags
        self.swaccess = swaccess
        self.hwaccess = hwaccess
        self.hwqe = hwqe
        self.bits = bits
        self.resval = resval
        self.enum = enum
        self.mubi = mubi

    @staticmethod
    def from_raw(reg_name: str,
                 field_idx: int,
                 num_fields: int,
                 default_swaccess: SWAccess,
                 default_hwaccess: HWAccess,
                 reg_resval: Optional[int],
                 reg_width: int,
                 params: ReggenParams,
                 hwext: bool,
                 default_hwqe: bool,
                 shadowed: bool,
                 is_alias: bool,
                 raw: object) -> 'Field':
        where = 'field {} of {} register'.format(field_idx, reg_name)
        rd = check_keys(raw, where,
                        list(REQUIRED_FIELDS.keys()),
                        list(OPTIONAL_FIELDS.keys()))

        raw_name = rd.get('name')
        if raw_name is None:
            name = ('field{}'.format(field_idx + 1)
                    if num_fields > 1 else reg_name)
        else:
            name = check_name(raw_name, 'name of {}'.format(where))

        alias_target = None
        if rd.get('alias_target') is not None:
            if is_alias:
                alias_target = check_name(rd.get('alias_target'),
                                          'name of alias target register')
            else:
                raise ValueError('Field {} may not have an alias_target key.'
                                 .format(name))

        raw_desc = rd.get('desc')
        if raw_desc is None and raw_name is not None:
            raise ValueError('Missing desc field for {}'
                             .format(where))
        if raw_desc is None:
            desc = None
        else:
            desc = check_str(raw_desc, 'desc field for {}'.format(where))

        tags = check_str_list(rd.get('tags', []),
                              'tags for {}'.format(where))

        raw_swaccess = rd.get('swaccess')
        if raw_swaccess is not None:
            swaccess = SWAccess(where, raw_swaccess)
        else:
            swaccess = default_swaccess

        raw_hwaccess = rd.get('hwaccess')
        if raw_hwaccess is not None:
            hwaccess = HWAccess(where, raw_hwaccess)
        else:
            hwaccess = default_hwaccess

        raw_hwqe = rd.get('hwqe', default_hwqe)
        hwqe = check_bool(raw_hwqe, 'hwqe field for {}'.format(where))

        raw_mubi = rd.get('mubi', False)
        is_mubi = check_bool(raw_mubi, 'mubi field for {}'.format(where))

        # Currently internal shadow registers do not support hw write type
        if not hwext and shadowed and hwaccess.allows_write():
            raise ValueError('Internal Shadow registers do not currently support '
                             'hardware write')

        bits = Bits.from_raw(where, reg_width, params, rd['bits'])
        raw_resval = rd.get('resval')
        if is_mubi:
            # When mubi type, the resval supplied is a boolean which is converted
            # to a mubi value
            chk_resval = check_bool(raw_resval, 'resval field for {}'.format(where))

            # Check mubi width is supported
            if not prim_mubi.is_width_valid(bits.width()):
                raise ValueError(f'mubi field for {name} does not support width '
                                 f'of {bits.width()}')

            # Get actual integer value based on mubi selection
            raw_resval = prim_mubi.mubi_value_as_int(chk_resval, bits.width())

        if raw_resval is None:
            # The field doesn't define a reset value. Use bits from reg_resval
            # if it's defined. If not, we assume that a hwext register comes up
            # as "x" (because the reggen code doesn't have any way to predict
            # it). That's represented as None. A non-hwext register is reset to
            # zero.
            if reg_resval is not None:
                resval = bits.extract_field(reg_resval)  # type: Optional[int]
            elif hwext:
                resval = None
            else:
                resval = 0
        else:
            # The field does define a reset value. It should be an integer or
            # 'x'. In the latter case, we set resval to None (as above).
            resval = check_xint(raw_resval, 'resval field for {}'.format(where))
            if resval is None:
                # We don't allow a field to be explicitly 'x' on reset but for
                # the containing register to have a reset value.
                if reg_resval is not None:
                    raise ValueError('resval field for {} is "x", but the '
                                     'register defines a resval as well.'
                                     .format(where))
            else:
                # Check that the reset value is representable with bits
                if not (0 <= resval <= bits.max_value()):
                    raise ValueError("resval field for {} is {}, which "
                                     "isn't representable as an unsigned "
                                     "{}-bit integer."
                                     .format(where, resval, bits.width()))

                # If the register had a resval, check this value matches it.
                if reg_resval is not None:
                    resval_from_reg = bits.extract_field(reg_resval)
                    if resval != resval_from_reg:
                        raise ValueError('resval field for {} is {}, but the '
                                         'register defines a resval as well, '
                                         'where bits {}:{} would give {}.'
                                         .format(where, resval,
                                                 bits.msb, bits.lsb,
                                                 resval_from_reg))

        raw_enum = rd.get('enum')
        if raw_enum is None:
            enum = None
        else:
            enum = []
            raw_entries = check_list(raw_enum,
                                     'enum field for {}'.format(where))
            enum_val_to_name = {}  # type: Dict[int, str]
            for idx, raw_entry in enumerate(raw_entries):
                entry = EnumEntry('entry {} in enum list for {}'
                                  .format(idx + 1, where),
                                  bits.max_value(),
                                  raw_entry)
                if entry.value in enum_val_to_name:
                    raise ValueError('In {}, duplicate enum entries for '
                                     'value {} ({} and {}).'
                                     .format(where,
                                             entry.value,
                                             enum_val_to_name[entry.value],
                                             entry.name))
                enum.append(entry)
                enum_val_to_name[entry.value] = entry.name

        return Field(name, alias_target, desc, tags, swaccess, hwaccess,
                     hwqe, bits, resval, enum, is_mubi)

    def has_incomplete_enum(self) -> bool:
        return (self.enum is not None and
                len(self.enum) != 1 + self.bits.max_value())

    def get_n_bits(self, hwext: bool, hwre: bool, bittype: List[str]) -> int:
        '''Get the size of this field in bits

        bittype should be a list of the types of signals to count. The elements
        should come from the following list:

        - 'q': A signal for the value of the field. Only needed if HW can read
          its contents.

        - 'd': A signal for the next value of the field. Only needed if HW can
          write its contents.

        - 'de': A write enable signal for hardware accesses. Only needed if HW
          can write the field's contents and the register data is stored in the
          register block (true if the hwext flag is false).

        '''
        n_bits = 0
        if "q" in bittype and self.hwaccess.allows_read():
            n_bits += self.bits.width()
        if "d" in bittype and self.hwaccess.allows_write():
            n_bits += self.bits.width()
        if "qe" in bittype and self.hwaccess.allows_read():
            n_bits += int(self.hwqe)
        if "re" in bittype and self.hwaccess.allows_read():
            n_bits += int(hwre)
        if "de" in bittype and self.hwaccess.allows_write():
            n_bits += int(not hwext)
        return n_bits

    def make_multi(self,
                   reg_width: int,
                   min_reg_idx: int,
                   max_reg_idx: int,
                   cname: str,
                   creg_idx: int,
                   stripped: bool) -> List['Field']:
        assert 0 <= min_reg_idx <= max_reg_idx

        # Check that we won't overflow reg_width. We assume that the LSB should
        # be preserved: if msb=5, lsb=2 then the replicated copies will be
        # [5:2], [11:8] etc.
        num_copies = 1 + max_reg_idx - min_reg_idx
        field_width = self.bits.msb + 1

        if field_width * num_copies > reg_width:
            raise ValueError('Cannot replicate field {} {} times: the '
                             'resulting width would be {}, but the register '
                             'width is just {}.'
                             .format(self.name, num_copies,
                                     field_width * num_copies, reg_width))

        desc = ('For {}{}'.format(cname, creg_idx)
                if stripped else self.desc)
        enum = None if stripped else self.enum

        ret = []
        for reg_idx in range(min_reg_idx, max_reg_idx + 1):
            name = '{}_{}'.format(self.name, reg_idx)
            # In case this is an alias register, we need to make sure that
            # the alias_target name is expanded as well.
            alias_target = None
            if self.alias_target is not None:
                alias_target = '{}_{}'.format(self.alias_target, reg_idx)

            bit_offset = field_width * (reg_idx - min_reg_idx)
            bits = (self.bits
                    if bit_offset == 0
                    else self.bits.make_translated(bit_offset))

            ret.append(Field(name, alias_target, desc,
                             self.tags, self.swaccess, self.hwaccess, self.hwqe,
                             bits, self.resval, enum, self.mubi))

        return ret

    def make_suffixed(self, suffix: str,
                      cname: str,
                      creg_idx: int,
                      stripped: bool) -> 'Field':
        desc = ('For {}{}'.format(cname, creg_idx)
                if stripped else self.desc)
        enum = None if stripped else self.enum

        alias_target = None
        if self.alias_target is not None:
            alias_target = self.alias_target + suffix

        return Field(self.name + suffix, alias_target,
                     desc, self.tags, self.swaccess, self.hwaccess, self.hwqe,
                     self.bits, self.resval, enum, self.mubi)

    def _asdict(self) -> Dict[str, object]:
        rd = {
            'bits': self.bits.as_str(),
            'name': self.name,
            'swaccess': self.swaccess.key,
            'hwaccess': self.hwaccess.key,
            'resval': 'x' if self.resval is None else str(self.resval),
            'tags': self.tags
        }  # type: Dict[str, object]

        if self.desc is not None:
            rd['desc'] = self.desc
        if self.enum is not None:
            rd['enum'] = self.enum
        if self.alias_target is not None:
            rd['alias_target'] = self.alias_target
        return rd

    def sw_readable(self) -> bool:
        return self.swaccess.key not in ['wo', 'r0w1c']

    def sw_writable(self) -> bool:
        return self.swaccess.key != 'ro'

    def apply_alias(self, alias_field: 'Field', where: str) -> None:
        '''Compare all attributes and replace overridable values.

        This updates the overridable field attributes with the alias values and
        ensures that all non-overridable attributes have identical values.
        '''

        # Attributes to be crosschecked
        attrs = ['bits', 'swaccess', 'hwaccess', 'hwqe', 'mubi']
        for attr in attrs:
            if getattr(self, attr) != getattr(alias_field, attr):
                raise ValueError('Value mismatch for attribute {} between '
                                 'alias field {} and field {} in {}.'
                                 .format(attr, self.name,
                                         alias_field.name, where))

        # These attributes can be overridden by the aliasing mechanism.
        self.name = alias_field.name
        self.desc = alias_field.desc
        self.enum = alias_field.enum
        self.resval = alias_field.resval
        self.tags = alias_field.tags
        # We also keep track of the alias_target when overriding attributes.
        # This gives us a way to check whether a register has been overridden
        # or not, and what the name of the original register was.
        self.alias_target = alias_field.alias_target

    def scrub_alias(self, where: str) -> None:
        '''Replaces sensitive fields in field with generic names

        This function can be used to create the generic field descriptions
        from full alias hjson definitions.
        '''
        # These attributes are scrubbed. Note that the name is scrubbed in
        # register.py already.
        self.desc = ''
        self.enum = []
        self.resval = 0
        self.tags = []
        self.alias_target = None
