#!/usr/bin/env python3
#
# Copyright (c) 2020 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

import logging
import struct


# Note: keep sync with C code
COREDUMP_HDR_ID = b'ZE'
COREDUMP_HDR_VER = 1
LOG_HDR_STRUCT = "<ccHHBBI"
LOG_HDR_SIZE = struct.calcsize(LOG_HDR_STRUCT)

COREDUMP_ARCH_HDR_ID = b'A'
LOG_ARCH_HDR_STRUCT = "<cHH"
LOG_ARCH_HDR_SIZE = struct.calcsize(LOG_ARCH_HDR_STRUCT)

COREDUMP_MEM_HDR_ID = b'M'
COREDUMP_MEM_HDR_VER = 1
LOG_MEM_HDR_STRUCT = "<cH"
LOG_MEM_HDR_SIZE = struct.calcsize(LOG_MEM_HDR_STRUCT)


logger = logging.getLogger("parser")


def reason_string(reason):
    # Keep sync with "enum k_fatal_error_reason"
    ret = "(Unknown)"

    if reason == 0:
        ret = "K_ERR_CPU_EXCEPTION"
    elif reason == 1:
        ret = "K_ERR_SPURIOUS_IRQ"
    elif reason == 2:
        ret = "K_ERR_STACK_CHK_FAIL"
    elif reason == 3:
        ret = "K_ERR_KERNEL_OOPS"
    elif reason == 4:
        ret = "K_ERR_KERNEL_PANIC"

    return ret


class CoredumpLogFile:
    """
    Process the binary coredump file for register block
    and memory blocks.
    """

    def __init__(self, logfile):
        self.logfile = logfile
        self.fd = None

        self.log_hdr = None
        self.arch_data = list()
        self.memory_regions = list()

    def open(self):
        self.fd = open(self.logfile, "rb")

    def close(self):
        self.fd.close()

    def get_arch_data(self):
        return self.arch_data

    def get_memory_regions(self):
        return self.memory_regions

    def parse_arch_section(self):
        hdr = self.fd.read(LOG_ARCH_HDR_SIZE)
        _, hdr_ver, num_bytes = struct.unpack(LOG_ARCH_HDR_STRUCT, hdr)

        arch_data = self.fd.read(num_bytes)

        self.arch_data = {"hdr_ver" : hdr_ver, "data" : arch_data}

        return True

    def parse_memory_section(self):
        hdr = self.fd.read(LOG_MEM_HDR_SIZE)
        _, hdr_ver = struct.unpack(LOG_MEM_HDR_STRUCT, hdr)

        if hdr_ver != COREDUMP_MEM_HDR_VER:
            logger.error(f"Memory block version: {hdr_ver}, expected {COREDUMP_MEM_HDR_VER}!")
            return False

        # Figure out how to read the start and end addresses
        ptr_fmt = None
        if self.log_hdr["ptr_size"] == 64:
            ptr_fmt = "QQ"
        elif self.log_hdr["ptr_size"] == 32:
            ptr_fmt = "II"
        else:
            return False

        data = self.fd.read(struct.calcsize(ptr_fmt))
        saddr, eaddr = struct.unpack(ptr_fmt, data)

        size = eaddr - saddr

        data = self.fd.read(size)

        mem = {"start": saddr, "end": eaddr, "data": data}
        self.memory_regions.append(mem)

        logger.info("Memory: 0x%x to 0x%x of size %d" %
                    (saddr, eaddr, size))

        return True

    def parse(self):
        if self.fd is None:
            self.open()

        hdr = self.fd.read(LOG_HDR_SIZE)
        id1, id2, hdr_ver, tgt_code, ptr_size, flags, reason = struct.unpack(LOG_HDR_STRUCT, hdr)

        if (id1 + id2) != COREDUMP_HDR_ID:
            # ID in header does not match
            logger.error("Log header ID not found...")
            return False

        if hdr_ver != COREDUMP_HDR_VER:
            logger.error(f"Log version: {hdr_ver}, expected: {COREDUMP_HDR_VER}!")
            return False

        ptr_size = 2 ** ptr_size

        self.log_hdr = {
                        "hdr_version": hdr_ver,
                        "tgt_code": tgt_code,
                        "ptr_size": ptr_size,
                        "flags": flags,
                        "reason": reason,
                        }

        logger.info("Reason: {0}".format(reason_string(reason)))
        logger.info(f"Pointer size {ptr_size}")

        del id1, id2, hdr_ver, tgt_code, ptr_size, flags, reason

        while True:
            section_id = self.fd.read(1)
            if not section_id:
                # no more data to read
                break

            self.fd.seek(-1, 1) # go back 1 byte
            if section_id == COREDUMP_ARCH_HDR_ID:
                if not self.parse_arch_section():
                    logger.error("Cannot parse architecture section")
                    return False
            elif section_id == COREDUMP_MEM_HDR_ID:
                if not self.parse_memory_section():
                    logger.error("Cannot parse memory section")
                    return False
            else:
                # Unknown section in log file
                logger.error(f"Unknown section in log file with ID {section_id}")
                return False

        return True
