import { createDocumentStore } from "./state-backend.js";
const DEFAULT_MAX_SAMPLES = 24 * 60;
export class MetricsHistoryStore {
    maxSamples;
    store;
    constructor(workspace, backend = "json", maxSamples = DEFAULT_MAX_SAMPLES) {
        this.maxSamples = maxSamples;
        this.store = createDocumentStore({
            workspace,
            backend,
            fileName: "metrics-history.json",
            sqliteKey: "metrics-history",
        });
    }
    list(limit = 240) {
        return this.payload().samples.slice(-Math.max(1, Math.min(this.maxSamples, limit))).reverse();
    }
    append(sample) {
        const normalized = normalizeSample(sample);
        this.store.update((current) => {
            const payload = this.normalizePayload(current);
            payload.samples = [...payload.samples, normalized]
                .sort((left, right) => Date.parse(left.at) - Date.parse(right.at))
                .slice(-this.maxSamples);
            return payload;
        });
        return normalized;
    }
    payload() {
        return this.normalizePayload(this.store.read());
    }
    normalizePayload(payload) {
        if (!payload || payload.version !== 1 || !Array.isArray(payload.samples)) {
            return { version: 1, samples: [] };
        }
        return {
            version: 1,
            samples: payload.samples.map(normalizeSample).slice(-this.maxSamples),
        };
    }
}
function normalizeSample(input) {
    return {
        at: validDate(input.at) ?? new Date().toISOString(),
        queueLength: number(input.queueLength),
        queuePaused: Boolean(input.queuePaused),
        activeTurns: number(input.activeTurns),
        failedTurns: number(input.failedTurns),
        runningJobs: number(input.runningJobs),
        failedJobs: number(input.failedJobs),
        rssBytes: number(input.rssBytes),
        heapUsedBytes: number(input.heapUsedBytes),
        cpuPercent: nullableNumber(input.cpuPercent),
        eventLoopP95Ms: nullableNumber(input.eventLoopP95Ms),
        eventLoopUtilizationPercent: nullableNumber(input.eventLoopUtilizationPercent),
        webAverageMs: nullableNumber(input.webAverageMs),
        webMaxMs: nullableNumber(input.webMaxMs),
        rateLimitHits: {
            telegram: number(input.rateLimitHits?.telegram),
            discord: number(input.rateLimitHits?.discord),
            slack: number(input.rateLimitHits?.slack),
            matrix: number(input.rateLimitHits?.matrix),
        },
    };
}
function number(value) {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : 0;
}
function nullableNumber(value) {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : null;
}
function validDate(value) {
    return typeof value === "string" && Number.isFinite(Date.parse(value)) ? value : undefined;
}
