# 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
from pw_cpu_exception_cortex_m_protos import cpu_state_pb2


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)


def process_snapshot(serialized_snapshot: bytes) -> str:
    """Returns the stringified result of a SnapshotCpuState message run though
    a CortexMExceptionAnalyzer.
    """
    snapshot = cpu_state_pb2.SnapshotCpuState()
    snapshot.ParseFromString(serialized_snapshot)

    if snapshot.HasField('armv7m_cpu_state'):
        return f'{CortexMExceptionAnalyzer(snapshot.armv7m_cpu_state)}\n'

    return ''
