# 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, Optional
from .clocks import Clocks


class ResetItem:
    '''Individual resets'''
    def __init__(self, hier: Dict[str, str], raw: Dict[str, object], clocks: Clocks):
        if not raw['name']:
            raise ValueError('Reset has no name')

        self.name = raw['name']
        self.gen = raw.get('gen', True)
        self.rst_type = raw.get('type', 'top')

        self.path = ""
        if self.rst_type == 'top':
            self.path = f"{hier['top']}rst_{self.name}_n"
        elif self.rst_type == 'ext':
            self.path = f"{hier['ext']}{self.name}"

        self.shadow_path = ""
        if self.rst_type == 'top':
            self.shadow_path = f"{hier['top']}rst_{self.name}_shadowed_n"

        # to be constructed later
        self.domains = []
        self.shadowed = False

        self.parent = raw.get('parent', "")

        # This can be a source clock or a derived source
        if self.rst_type != 'ext':
            self.clock = clocks.get_clock_by_name(raw['clk'])
        else:
            self.clock = None

        self.sw = bool(raw.get('sw', 0))

    def _asdict(self) -> Dict[str, object]:
        ret = {
            'name': self.name,
            'gen': self.gen,
            'type': self.rst_type,
            'domains': self.domains,
            'shadowed': self.shadowed,
            'sw': self.sw,
            'path': self.path
        }

        if self.parent:
            ret['parent'] = self.parent

        if self.clock:
            ret['clock'] = self.clock.name

        return ret


class Resets:
    '''Resets for the chip'''
    def __init__(self, raw: Dict[str, object], clocks: Clocks):
        self.hier_paths = {}
        assert isinstance(raw['hier_paths'], dict)
        for rst_src, path in raw['hier_paths'].items():
            self.hier_paths[str(rst_src)] = str(path)

        assert isinstance(raw['nodes'], list)

        self.nodes = {}
        for node in raw['nodes']:
            assert isinstance(node, dict)
            reset = ResetItem(self.hier_paths, node, clocks)
            self.nodes[reset.name] = reset

    def _asdict(self) -> Dict[str, object]:
        ret = {
            'hier_paths': self.hier_paths,
            'nodes': list(self.nodes.values())
        }

        return ret

    def get_reset_by_name(self, name: str) -> ResetItem:

        ret = self.nodes.get(name, None)
        if ret:
            return ret
        else:
            raise ValueError(f'{name} is not a defined reset')

    def mark_reset_shadowed(self, name: str):
        '''Mark particular reset as requiring shadow'''

        reset = self.get_reset_by_name(name)
        reset.shadowed = True

    def get_reset_domains(self, name: str):
        '''Get available domains for a reset'''

        return self.get_reset_by_name(name).domains

    def get_clocks(self) -> list:
        '''Get associated clocks'''

        clocks = {}
        for reset in self.nodes.values():
            if reset.rst_type != 'ext':
                clocks[reset.clock.name] = 1

        return clocks.keys()

    def get_generated_resets(self) -> list:
        '''Get generated resets and return reset object
        '''
        return [reset
                for reset in self.nodes.values()
                if reset.gen]


    def get_top_resets(self) -> list:
        '''Get resets pushed to the top level'''

        return [reset
                for reset in self.nodes.values()
                if reset.rst_type == 'top']

    def get_sw_resets(self) -> list:
        '''Get software controlled resets'''

        return [reset.name
                for reset in self.nodes.values()
                if reset.sw]

    def get_path(self, name: str, domain: Optional[str], shadow = False) -> str:
        '''Get path to reset'''

        reset = self.get_reset_by_name(name)
        if reset.rst_type == 'int':
            raise ValueError(f'Reset {name} is not a reset exported from rstmgr')

        if reset.rst_type == 'ext':
            return reset.path


        if shadow:
            path = reset.shadow_path
        else:
            path = reset.path

        if domain:
            path += f'[rstmgr_pkg::Domain{domain}Sel]'

        return path


    def get_unused_resets(self, domains: list) -> Dict[str, str]:
        '''Get unused resets'''

        top_resets = [reset
                      for reset in self.nodes.values()
                      if reset.rst_type == 'top']

        ret = {}
        for reset in top_resets:
            for dom in domains:
                if dom not in reset.domains:
                    doml = dom.lower()
                    ret[f'unused_d{doml}_rst_{reset.name}'] = \
                        f'{reset.path}[rstmgr_pkg::Domain{dom}Sel]'

                    if reset.shadowed:
                        ret[f'unused_d{doml}_rst_{reset.name}_shadowed'] = \
                            f'{reset.shadow_path}[rstmgr_pkg::Domain{dom}Sel]'

        return ret

    def add_reset_domain(self, name: str, domain: str):
        '''Mark particular reset as requiring shadow'''

        reset = self.get_reset_by_name(name)

        # Other reset types of hardwired domains
        if reset.rst_type == 'top':
            if domain not in reset.domains:
                reset.domains.append(domain)

    def has_shadowed_reset(self) -> bool:
        '''Do any generated resets have a shadow version?'''

        for reset in self.nodes.values():
            if reset.shadowed:
                return True

        return False
