"use strict";
/**
 * Trust Score Time-Series Snapshotter.
 *
 * Records per-agent three-dimensional score snapshots over time. Drives the
 * dashboard trust-curve display (Q1 runtime view's secondary panel, plus
 * the per-agent detail page).
 *
 * Pure in-memory store with sorted-by-time invariants. Persistence to
 * Postgres is a follow-up slice (would wire the same API to Prisma).
 *
 * @connexum/ai-governance  Trust-score time-series (dashboard support)
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.TrustScoreSnapshotStore = void 0;
class TrustScoreSnapshotStore {
    byAgent = new Map();
    record(snapshot) {
        if (!snapshot.agentId || snapshot.agentId.trim() === '') {
            throw new Error('TrustScoreSnapshotStore.record: agentId is required');
        }
        if (!snapshot.at || Number.isNaN(new Date(snapshot.at).getTime())) {
            throw new Error('TrustScoreSnapshotStore.record: at must be a valid ISO 8601 timestamp');
        }
        const list = this.byAgent.get(snapshot.agentId) ?? [];
        list.push(snapshot);
        list.sort((a, b) => new Date(a.at).getTime() - new Date(b.at).getTime());
        this.byAgent.set(snapshot.agentId, list);
    }
    /** Returns snapshots ordered by time ascending, optionally filtered by range. */
    getTimeSeries(agentId, range) {
        const list = this.byAgent.get(agentId) ?? [];
        if (!range)
            return [...list];
        const fromMs = range.from ? new Date(range.from).getTime() : -Infinity;
        const toMs = range.to ? new Date(range.to).getTime() : Infinity;
        return list.filter((s) => {
            const t = new Date(s.at).getTime();
            return t >= fromMs && t <= toMs;
        });
    }
    /**
     * Compute the score delta over a range (first vs last snapshot in window).
     * Returns null when fewer than 2 snapshots fall in the range.
     */
    computeDelta(agentId, range) {
        const series = this.getTimeSeries(agentId, range);
        if (series.length < 2)
            return null;
        const first = series[0];
        const last = series[series.length - 1];
        return {
            agentId,
            fromIso: first.at,
            toIso: last.at,
            delta: {
                agent_activity: last.score.agent_activity.composite - first.score.agent_activity.composite,
                operator_activity: last.score.operator_activity.composite - first.score.operator_activity.composite,
                agent_build_structure: last.score.agent_build_structure.composite - first.score.agent_build_structure.composite,
                composite: last.score.composite - first.score.composite,
            },
            sampleCount: series.length,
        };
    }
    /** List every agent that has at least one recorded snapshot. */
    listAgents() {
        return Array.from(this.byAgent.keys()).sort();
    }
    /** Most recent snapshot for an agent, or undefined if none recorded. */
    getLatest(agentId) {
        const list = this.byAgent.get(agentId);
        if (!list || list.length === 0)
            return undefined;
        return list[list.length - 1];
    }
    /**
     * Down-sample to at most `maxPoints` evenly spaced snapshots — useful for
     * sparkline charts on the dashboard where 1000-point series produce no
     * additional information than ~50.
     */
    downsample(agentId, maxPoints, range) {
        if (maxPoints <= 0) {
            throw new Error('TrustScoreSnapshotStore.downsample: maxPoints must be > 0');
        }
        const series = this.getTimeSeries(agentId, range);
        if (series.length <= maxPoints)
            return series;
        const stride = (series.length - 1) / (maxPoints - 1);
        const out = [];
        for (let i = 0; i < maxPoints; i++) {
            const idx = Math.round(i * stride);
            out.push(series[idx]);
        }
        return out;
    }
}
exports.TrustScoreSnapshotStore = TrustScoreSnapshotStore;
//# sourceMappingURL=trust-score-snapshot.js.map