# 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 .access import SWAccess, HWAccess
from .bits import Bits
from .enum_entry import EnumEntry
from .lib import (check_keys, check_str, check_name,
                  check_list, check_str_list, check_xint)
from .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)"],
    '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.)"
    ],
    '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...'"
    ]
}


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

    @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,
                 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))

        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

        bits = Bits.from_raw(where, reg_width, params, rd['bits'])

        raw_resval = rd.get('resval')
        if raw_resval is None:
            # The field doesn't define a reset value. Use bits from reg_resval
            # if it's defined, otherwise None (which means "x").
            if reg_resval is None:
                resval = None
            else:
                resval = bits.extract_field(reg_resval)
        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, desc, tags, swaccess, hwaccess, bits, resval, enum)

    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, hwqe: 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(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)

            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, desc,
                             self.tags, self.swaccess, self.hwaccess,
                             bits, self.resval, enum))

        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

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

    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
        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'
