# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Tools to analyze Cortex-M CPU state context captured during an exception."""

from typing import Tuple

from pw_cpu_exception_cortex_m import cortex_m_constants


class CortexMExceptionAnalyzer:
    """This class provides helper functions to dump a ArmV7mCpuState proto."""
    def __init__(self, cpu_state):
        self._cpu_state = cpu_state
        self._active_cfsr_fields = None

    def active_cfsr_fields(self) -> Tuple[cortex_m_constants.BitField, ...]:
        """Returns a list of BitFields for each active CFSR flag."""

        if self._active_cfsr_fields is not None:
            return self._active_cfsr_fields

        temp_field_list = []
        if self._cpu_state.HasField('cfsr'):
            for bit_field in cortex_m_constants.PW_CORTEX_M_CFSR_BIT_FIELDS:
                if self._cpu_state.cfsr & bit_field.bit_mask:
                    temp_field_list.append(bit_field)
        self._active_cfsr_fields = tuple(temp_field_list)
        return self._active_cfsr_fields

    def is_fault_active(self) -> bool:
        """Returns true if the current CPU state indicates a fault is active."""
        if self._cpu_state.HasField('cfsr') and self._cpu_state.cfsr != 0:
            return True
        if self._cpu_state.HasField('icsr'):
            exception_number = (
                self._cpu_state.icsr
                & cortex_m_constants.PW_CORTEX_M_ICSR_VECTACTIVE_MASK)
            if (cortex_m_constants.PW_CORTEX_M_HARD_FAULT_ISR_NUM <=
                    exception_number <=
                    cortex_m_constants.PW_CORTEX_M_USAGE_FAULT_ISR_NUM):
                return True
        return False

    def is_nested_fault(self) -> bool:
        """Returns true if the current CPU state indicates a nested fault."""
        if not self.is_fault_active():
            return False
        if (self._cpu_state.HasField('hfsr') and self._cpu_state.hfsr
                & cortex_m_constants.PW_CORTEX_M_HFSR_FORCED_MASK):
            return True
        return False

    def exception_cause(self, show_active_cfsr_fields=True) -> str:
        """Analyzes CPU state to tries and classify the exception.

        Examples:
            show_active_cfsr_fields=False
              unknown exception
              memory management fault at 0x00000000
              usage fault, imprecise bus fault

            show_active_cfsr_fields=True
              usage fault [DIVBYZERO]
              memory management fault at 0x00000000 [DACCVIOL] [MMARVALID]
        """
        cause = ''
        # The CFSR can accumulate multiple exceptions.
        split_major_cause = lambda cause: cause if not cause else cause + ', '

        if self._cpu_state.HasField('cfsr') and self.is_fault_active():
            if (self._cpu_state.cfsr
                    & cortex_m_constants.PW_CORTEX_M_CFSR_USAGE_FAULT_MASK):
                cause += 'usage fault'

            if (self._cpu_state.cfsr
                    & cortex_m_constants.PW_CORTEX_M_CFSR_MEM_FAULT_MASK):
                cause = split_major_cause(cause)
                cause += 'memory management fault'
                if (self._cpu_state.cfsr
                        & cortex_m_constants.PW_CORTEX_M_CFSR_MMARVALID_MASK):
                    addr = '???' if not self._cpu_state.HasField(
                        'mmfar') else f'0x{self._cpu_state.mmfar:08x}'
                    cause += f' at {addr}'

            if (self._cpu_state.cfsr
                    & cortex_m_constants.PW_CORTEX_M_CFSR_BUS_FAULT_MASK):
                cause = split_major_cause(cause)
                if (self._cpu_state.cfsr &
                        cortex_m_constants.PW_CORTEX_M_CFSR_IMPRECISERR_MASK):
                    cause += 'imprecise '
                cause += 'bus fault'
                if (self._cpu_state.cfsr
                        & cortex_m_constants.PW_CORTEX_M_CFSR_BFARVALID_MASK):
                    addr = '???' if not self._cpu_state.HasField(
                        'bfar') else f'0x{self._cpu_state.bfar:08x}'
                    cause += f' at {addr}'
            if show_active_cfsr_fields:
                for field in self.active_cfsr_fields():
                    cause += f' [{field.name}]'

        return cause if cause else 'unknown exception'

    def dump_registers(self) -> str:
        """Dumps all captured CPU registers as a multi-line string."""
        registers = []
        # TODO(amontanez): Do fancier decode of some registers like PC and LR.
        for field in self._cpu_state.DESCRIPTOR.fields:
            if self._cpu_state.HasField(field.name):
                register_value = getattr(self._cpu_state, field.name)
                registers.append(f'{field.name:<10} 0x{register_value:08x}')
        return '\n'.join(registers)

    def dump_active_active_cfsr_fields(self) -> str:
        """Dumps CFSR flags with their descriptions as a multi-line string."""
        fields = []
        for field in self.active_cfsr_fields():
            fields.append(f'{field.name:<11} {field.description}')
            if isinstance(field.long_description, tuple):
                long_desc = '    {}'.format('\n    '.join(
                    field.long_description))
                fields.append(long_desc)
        return '\n'.join(fields)

    def __str__(self):
        dump = [f'Exception caused by a {self.exception_cause(False)}.', '']
        if self.active_cfsr_fields():
            dump.extend((
                'Active Crash Fault Status Register (CFSR) fields:',
                self.dump_active_active_cfsr_fields(),
                '',
            ))
        else:
            dump.extend((
                'No active Crash Fault Status Register (CFSR) fields.',
                '',
            ))
        dump.extend((
            'All registers:',
            self.dump_registers(),
        ))
        return '\n'.join(dump)
