# 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 .field_enums import HwAccess, SwAccess, SwRdAccess, SwWrAccess


# helper funtion that strips trailing _number (used as multireg suffix) from name
# TODO: this is a workaround, should solve this in validate.py
def _get_basename(name):
    for (k, c) in enumerate(name[::-1]):
        if not str.isdigit(c):
            if c == "_":
                return name[0:len(name) - (k + 1)]
            else:
                break
    return ""


class Field():
    """Field in a register.

    Field class contains necessary info to generate RTL code.
    It has two additional (tool generated) fields, swrdaccess and swwraccess,
    which represent read and write type. This makes RTL generation code simpler.
    """
    def __init__(self):
        self.name = ""  # required
        self.msb = 31  # required
        self.lsb = 0  # required
        self.resval = 0  # optional
        self.swaccess = SwAccess.NONE  # optional
        self.swrdaccess = SwRdAccess.NONE
        self.swwraccess = SwWrAccess.NONE
        self.hwaccess = HwAccess.HRO
        self.hwqe = False
        self.hwre = False
        self.hwext = False
        self.tags = []
        self.shadowed = False

    def get_n_bits(self, bittype=["q"]):
        n_bits = 0
        if "q" in bittype and self.hwaccess in [HwAccess.HRW, HwAccess.HRO]:
            n_bits += self.msb - self.lsb + 1
        if "d" in bittype and self.hwaccess in [HwAccess.HRW, HwAccess.HWO]:
            n_bits += self.msb - self.lsb + 1
        if "qe" in bittype and self.hwaccess in [HwAccess.HRW, HwAccess.HRO]:
            n_bits += self.hwqe
        if "re" in bittype and self.hwaccess in [HwAccess.HRW, HwAccess.HRO]:
            n_bits += self.hwre
        if "de" in bittype and self.hwaccess in [HwAccess.HRW, HwAccess.HWO]:
            n_bits += not self.hwext
        return n_bits

    def get_fields_flat(self):
        return [self]

    def get_basename(self):
        return _get_basename(self.name)


class Reg():
    def __init__(self, name=""):
        self.name = name
        self.offset = 0
        self.hwqe = False
        self.hwre = False
        self.hwext = False  # External register
        self.resval = 0
        self.dvrights = "RO"  # Used by UVM REG only
        self.regwen = ""
        self.fields = []
        self.width = 0
        self.ishomog = 0
        self.tags = []
        self.shadowed = False

    def is_multi_reg(self):
        """Returns true if this is a multireg"""
        return False

    def get_n_bits(self, bittype=["q"]):
        """Returns number of bits in this register (including all multiregs and
        fields). By default this function counts read data bits (bittype "q"),
        but other bits such as "d", qe", "re", "de" can be counted as well by
        specifying them in the bittype list argument.
        """
        n_bits = 0
        for f in self.fields:
            n_bits += f.get_n_bits(bittype)
        return n_bits

    def get_fields_flat(self):
        """Returns a flat list of all the fields in this register"""
        fields = []
        for f in self.fields:
            fields += f.get_fields_flat()
        return fields

    def get_field_flat(self, linear_idx):
        """Returns a specific field at a linear index position in
        the flattened field list"""
        fields_flat = self.get_fields_flat()
        return fields_flat[linear_idx]

    def get_n_fields_flat(self):
        """Returns the number of fields contained in the flat field list"""
        return len(self.get_fields_flat())

    def get_regs_flat(self):
        """Returns a flat list containing all
        registers and subregisters"""
        if isinstance(self.fields[0], Field):
            return [self]
        else:
            regs = []
            for r in self.fields:
                regs += r.get_regs_flat()
            return regs

    def get_reg_flat(self, linear_index):
        """Returns a specific register at a linear index position in
        the flattened regiser list"""
        regs_flat = self.get_regs_flat()
        return regs_flat[linear_index]

    def get_n_regs_flat(self):
        """Returns the number of registers contained in
        the flat register list"""
        return len(self.get_regs_flat())

    def get_nested_dims(self):
        """Recursively get dimensions of nested registers (outputs a list)"""
        # return length of flattened field array if this is a regular register,
        # or if this is the last multiregister level in a nested multiregister
        if not isinstance(self, MultiReg):
            dims = [len(self.get_fields_flat())]
        if isinstance(self, MultiReg) and\
           not isinstance(self.fields[0], MultiReg):
            if self.ishomog:
                dims = [len(self.get_fields_flat())]
            else:
                dims = [len(self.fields)]
        else:
            # nested multiregister case
            dims = [len(self.fields)] + self.fields[0].get_nested_dims()
        return dims

    def get_nested_params(self):
        """Recursively get parameters of nested registers (outputs a list)"""
        params = []
        if isinstance(self, MultiReg):
            params += [self.param]
        if isinstance(self.fields[0], MultiReg):
            params += self.fields[0].get_nested_params()
        return params

    def get_basename(self):
        return _get_basename(self.name)


class MultiReg(Reg):
    def __init__(self, name):
        Reg.__init__(self, name)
        self.param = ""

    def is_multi_reg(self):
        """Returns true if this is a multireg"""
        return True


class Window():
    def __init__(self):
        self.base_addr = 0
        self.byte_write = 0
        self.limit_addr = 0
        self.n_bits = 0
        self.tags = []


class Block():
    def __init__(self):
        self.width = 32
        self.addr_width = 12
        # Key is instance name
        self.base_addr = OrderedDict()
        self.name = ""
        self.hier_path = ""
        self.regs = []
        self.wins = []
        self.blocks = []
        self.params = []
        self.tags = []

    def get_regs_flat(self):
        """Returns flattened register list
        """
        regs = []
        for r in self.regs:
            regs += r.get_regs_flat()
        return regs

    def get_n_bits(self, bittype=["q"]):
        """Returns number of bits in this block (including all multiregs and
        fields). By default this function counts read data bits (bittype "q"),
        but other bits such as "d", qe", "re", "de" can be counted as well by
        specifying them in the bittype list argument.
        """
        n_bits = 0
        for r in self.regs:
            n_bits += r.get_n_bits(bittype)
        return n_bits

    def get_n_regs_flat(self):
        return len(self.get_regs_flat())

    def contains_multiregs(self):
        """Returns true if there are multiregs in this block
        """
        for r in self.regs:
            if isinstance(r, MultiReg):
                return True
        return False
