const runRouteById = new Map();
const runMetadataById = new Map();
const finalDeliveredRunIds = new Set();
/** Vitest / harness: clears per-run metadata and final-delivered flags (not routes). */
export function resetRunMetadataForTest() {
    runMetadataById.clear();
    finalDeliveredRunIds.clear();
}
export function registerRunRoute(route) {
    if (!route.runId.trim())
        return;
    runRouteById.set(route.runId, route);
}
export function getRunRoute(runId) {
    return runRouteById.get(runId);
}
export function setRunMetadata(runId, metadata) {
    if (!runId.trim())
        return;
    const existing = runMetadataById.get(runId) ?? {};
    runMetadataById.set(runId, { ...existing, ...metadata });
}
export function getRunMetadata(runId) {
    return runMetadataById.get(runId);
}
export function markRunFinalDelivered(runId) {
    if (!runId.trim())
        return;
    finalDeliveredRunIds.add(runId);
}
export function hasRunFinalDelivered(runId) {
    return finalDeliveredRunIds.has(runId);
}
function finiteNumber(value) {
    if (typeof value === "number" && Number.isFinite(value))
        return value;
    return undefined;
}
function recordValue(value) {
    if (value && typeof value === "object" && !Array.isArray(value)) {
        return value;
    }
    return null;
}
function pickInputTokens(u) {
    return (finiteNumber(u.input) ??
        finiteNumber(u.inputTokens) ??
        finiteNumber(u.input_tokens) ??
        finiteNumber(u.promptTokens) ??
        finiteNumber(u.prompt_tokens) ??
        finiteNumber(u.prompt_n));
}
function pickOutputTokens(u) {
    return (finiteNumber(u.output) ??
        finiteNumber(u.outputTokens) ??
        finiteNumber(u.output_tokens) ??
        finiteNumber(u.completionTokens) ??
        finiteNumber(u.completion_tokens) ??
        finiteNumber(u.predicted_n));
}
function pickCacheRead(u) {
    const inDet = recordValue(u.input_tokens_details);
    const prDet = recordValue(u.prompt_tokens_details);
    return (finiteNumber(u.cacheRead) ??
        finiteNumber(u.cache_read) ??
        finiteNumber(u.cache_read_input_tokens) ??
        finiteNumber(u.cached_tokens) ??
        (inDet ? finiteNumber(inDet.cached_tokens) : undefined) ??
        (prDet ? finiteNumber(prDet.cached_tokens) : undefined));
}
function pickCacheWrite(u) {
    return (finiteNumber(u.cacheWrite) ??
        finiteNumber(u.cache_write) ??
        finiteNumber(u.cache_creation_input_tokens));
}
/** Best-effort prompt-side context footprint from a provider usage object. */
export function contextTokensFromUsageRecord(u) {
    const inp = pickInputTokens(u);
    const cr = pickCacheRead(u);
    const cw = pickCacheWrite(u);
    const total = finiteNumber(u.total) ?? finiteNumber(u.total_tokens) ?? finiteNumber(u.totalTokens);
    const out = pickOutputTokens(u);
    if (inp !== undefined || cr !== undefined || cw !== undefined) {
        return Math.max(0, Math.floor((inp ?? 0) + (cr ?? 0) + (cw ?? 0)));
    }
    if (total !== undefined && out !== undefined && total >= out) {
        return Math.max(0, Math.floor(total - out));
    }
    return undefined;
}
function pickContextWindowMaxFromData(data) {
    const v = finiteNumber(data.contextWindow) ??
        finiteNumber(data.context_window) ??
        finiteNumber(data.maxContextTokens) ??
        finiteNumber(data.max_context_tokens);
    if (typeof v === "number" && v > 0)
        return Math.floor(v);
    return undefined;
}
export function ingestAgentEventMetadata(runId, data) {
    if (!runId.trim())
        return;
    const next = {};
    const modelName = (typeof data.modelName === "string" && data.modelName.trim()) ||
        (typeof data.model === "string" && data.model.trim()) ||
        undefined;
    if (modelName)
        next.modelName = modelName;
    const usage = recordValue(data.usage);
    const totalTokens = finiteNumber(data.totalTokens) ??
        finiteNumber(data.total_tokens) ??
        finiteNumber(usage?.totalTokens) ??
        finiteNumber(usage?.total_tokens) ??
        finiteNumber(usage?.total);
    if (typeof totalTokens === "number" && totalTokens > 0) {
        next.totalTokens = Math.floor(totalTokens);
    }
    const usageForContext = usage ?? data;
    const ctxUsed = contextTokensFromUsageRecord(usageForContext);
    if (typeof ctxUsed === "number" && ctxUsed > 0) {
        next.contextTokensUsed = ctxUsed;
    }
    const ctxMax = pickContextWindowMaxFromData(data);
    if (typeof ctxMax === "number") {
        next.contextWindowMax = ctxMax;
    }
    if (!next.contextWindowMax && usage) {
        const fromUsage = pickContextWindowMaxFromData(usage);
        if (typeof fromUsage === "number") {
            next.contextWindowMax = fromUsage;
        }
    }
    if (next.modelName ||
        typeof next.totalTokens === "number" ||
        typeof next.contextTokensUsed === "number" ||
        typeof next.contextWindowMax === "number") {
        setRunMetadata(runId, next);
    }
}
