/**
 * Per-tool invocation ring buffer and health aggregator.
 *
 * Stores the last RING_SIZE durations per tool (ok + error separately).
 * Used by dispatch.ts to record each call; exposed via /api/runtime/tool-health.
 */
const RING_SIZE = 100;
const ERROR_RATE_WINDOW_MS = 5 * 60 * 1000; // 5-minute sliding window for error rate
const _rings = new Map();
export function recordToolInvocation(toolName, durationMs, status) {
    let ring = _rings.get(toolName);
    if (!ring) {
        ring = [];
        _rings.set(toolName, ring);
    }
    ring.push({ ts: Date.now(), durationMs, status });
    if (ring.length > RING_SIZE)
        ring.shift();
}
function percentile(sorted, p) {
    if (!sorted.length)
        return 0;
    const idx = Math.ceil((p / 100) * sorted.length) - 1;
    return sorted[Math.max(0, idx)];
}
export function getToolHealthSummary() {
    const now = Date.now();
    const result = [];
    for (const [toolName, ring] of _rings) {
        if (!ring.length)
            continue;
        const windowStart = now - ERROR_RATE_WINDOW_MS;
        const recent = ring.filter(r => r.ts >= windowStart);
        const allDurations = ring.map(r => r.durationMs).sort((a, b) => a - b);
        const errors = recent.filter(r => r.status === 'error').length;
        const errorRate = recent.length > 0 ? errors / recent.length : 0;
        const p50Ms = percentile(allDurations, 50);
        const p95Ms = percentile(allDurations, 95);
        const lastSeenMs = ring[ring.length - 1].ts;
        // Red: error rate > 5% OR p95 > 5s in last 5 min
        // Amber: error rate > 1% OR p95 > 2s
        let status;
        if (errorRate > 0.05 || p95Ms > 5_000)
            status = 'red';
        else if (errorRate > 0.01 || p95Ms > 2_000)
            status = 'amber';
        else
            status = 'green';
        result.push({ toolName, p50Ms, p95Ms, errorRate, recentCount: recent.length, lastSeenMs, status });
    }
    // Sort: red first, then amber, then green; within tier sort by p95 desc
    return result.sort((a, b) => {
        const tier = { red: 0, amber: 1, green: 2 };
        const td = tier[a.status] - tier[b.status];
        return td !== 0 ? td : b.p95Ms - a.p95Ms;
    });
}
