/*
    * CrashReportSyscall.hpp
    * SYS_CRASH_REPORT
    * Copyright (c) 2026 Daniel Hammer
*/

#pragma once
#include <cstdint>
#include "Syscall.hpp"
#include "../Sched/CrashReport.hpp"

namespace Montauk {

    static int64_t Sys_CrashReport(CrashReportInfo* out) {
        if (!out) return 0;
        if (CrashReport::g_reportCount == 0) return 0;

        int oldestIdx = (CrashReport::g_reportHead - CrashReport::g_reportCount + CrashReport::MaxReports) % CrashReport::MaxReports;
        auto* rep = &CrashReport::g_reports[oldestIdx];

        out->pid = rep->pid;
        for (int i = 0; i < 64 && rep->processName[i]; i++) out->processName[i] = rep->processName[i];
        out->processName[63] = '\0';
        out->exceptionVector = rep->exceptionVector;
        for (int i = 0; i < 32 && rep->exceptionName[i]; i++) out->exceptionName[i] = rep->exceptionName[i];
        out->exceptionName[31] = '\0';
        out->faultingAddress = rep->faultingAddress;
        out->instructionPointer = rep->instructionPointer;
        out->stackPointer = rep->stackPointer;
        out->codeSegment = rep->codeSegment;
        out->flags = rep->flags;
        out->stackSegment = rep->stackSegment;
        out->pfPresent = rep->pfPresent;
        out->pfWrite = rep->pfWrite;
        out->pfUser = rep->pfUser;
        out->pfReservedWrite = rep->pfReservedWrite;
        out->pfInstructionFetch = rep->pfInstructionFetch;
        out->pfProtectionKey = rep->pfProtectionKey;
        out->pfShadowStack = rep->pfShadowStack;
        out->pfSGX = rep->pfSGX;
        out->timestampTick = rep->timestampTick;
        rep->valid = false;
        CrashReport::g_reportCount--;

        return CrashReport::g_reportCount + 1;
    }

}
