/*
    * CrashReport.cpp
    * Structured crash report implementation
    * Copyright (c) 2026 Daniel Hammer
*/

#include "CrashReport.hpp"
#include <CppLib/Spinlock.hpp>

namespace CrashReport {

Report g_reports[MaxReports];
int g_reportHead = 0;
int g_reportCount = 0;

// Serializes ring-buffer access. Interrupt-disabling: the writer runs inside
// the exception handler (IF=0) while readers come from syscall context.
static kcp::Spinlock g_lock;

void AddReport(const Report& report) {
    g_lock.Acquire();
    g_reports[g_reportHead] = report;
    g_reportHead = (g_reportHead + 1) % MaxReports;
    if (g_reportCount < MaxReports) g_reportCount++;
    g_lock.Release();
}

int TakeOldest(Report& out) {
    g_lock.Acquire();
    int had = g_reportCount;
    if (had == 0) {
        g_lock.Release();
        return 0;
    }
    int oldestIdx = (g_reportHead - g_reportCount + MaxReports) % MaxReports;
    out = g_reports[oldestIdx];
    g_reports[oldestIdx].valid = false;
    g_reportCount--;
    g_lock.Release();
    return had;
}

} // namespace CrashReport
