"use strict";
/**
 * JSON file output plugin.
 *
 * Assembles the BenchmarkData structure from all upstream plugin data
 * and writes it to a JSON file. Returns the BenchmarkData for backward compat.
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonWriterPlugin = void 0;
const ui_1 = require("../../../ui");
const chalk_1 = __importDefault(require("chalk"));
const debug_1 = require("../../../utils/debug");
const atomic_write_js_1 = require("../../../utils/atomic-write.js");
const agent_interface_1 = require("../../agent-interface");
/**
 * Sum token usage across all models from the SDK's modelUsage field.
 */
function sumModelUsage(modelUsage) {
    let input_tokens = 0;
    let output_tokens = 0;
    let cache_creation_input_tokens = 0;
    let cache_read_input_tokens = 0;
    for (const model of Object.values(modelUsage)) {
        input_tokens += model.inputTokens ?? 0;
        output_tokens += model.outputTokens ?? 0;
        cache_creation_input_tokens += model.cacheCreationInputTokens ?? 0;
        cache_read_input_tokens += model.cacheReadInputTokens ?? 0;
    }
    return {
        input_tokens,
        output_tokens,
        cache_creation_input_tokens,
        cache_read_input_tokens,
    };
}
class JsonWriterPlugin {
    name = 'jsonWriter';
    outputPath;
    constructor(outputPath) {
        this.outputPath = outputPath;
    }
    onFinalize(resultMessage, totalDurationMs, ctx, _store) {
        const tokens = ctx.get('tokens');
        const cache = ctx.get('cache');
        const turns = ctx.get('turns');
        const cost = ctx.get('cost');
        const duration = ctx.get('duration');
        const compactions = ctx.get('compactions');
        const contextSize = ctx.get('contextSize');
        const modelUsage = resultMessage?.modelUsage ?? {};
        const aggregateUsage = sumModelUsage(modelUsage);
        const phaseSnapshots = duration?.phaseSnapshots ?? [];
        const steps = [];
        for (let i = 0; i < phaseSnapshots.length; i++) {
            const dur = phaseSnapshots[i];
            const tokenSnap = tokens?.phaseSnapshots[i];
            const cacheSnap = cache?.phaseSnapshots[i];
            const turnSnap = turns?.phaseSnapshots[i];
            const costSnap = cost?.phaseCosts[i];
            const compSnap = compactions?.phaseSnapshots[i];
            const ctxSnap = contextSize?.phaseSnapshots[i];
            const step = {
                name: dur.phase,
                usage: {
                    input_tokens: tokenSnap?.inputTokens ?? 0,
                    output_tokens: tokenSnap?.outputTokens ?? 0,
                    cache_creation_input_tokens: cacheSnap?.cacheCreationTokens ?? 0,
                    cache_read_input_tokens: cacheSnap?.cacheReadTokens ?? 0,
                    ...((cacheSnap?.cacheCreation5m ?? 0) +
                        (cacheSnap?.cacheCreation1h ?? 0) >
                        0 && {
                        cache_creation: {
                            ephemeral_5m_input_tokens: cacheSnap?.cacheCreation5m ?? 0,
                            ephemeral_1h_input_tokens: cacheSnap?.cacheCreation1h ?? 0,
                        },
                    }),
                },
                modelUsage: {},
                totalCostUsd: costSnap?.cost ?? 0,
                durationMs: dur.durationMs,
                durationApiMs: 0,
                numTurns: turnSnap?.turns ?? 0,
                ...(ctxSnap?.contextTokensIn !== undefined && {
                    contextTokensIn: ctxSnap.contextTokensIn,
                }),
                ...(ctxSnap?.contextTokensOut !== undefined && {
                    contextTokensOut: ctxSnap.contextTokensOut,
                }),
                ...(compSnap && compSnap.compactions > 0
                    ? {
                        compactions: compSnap.compactions,
                        compactionPreTokens: compSnap.preTokens,
                    }
                    : {}),
            };
            steps.push(step);
        }
        const totalTurns = turns?.totalTurns ?? 0;
        const totalCost = cost?.totalCost ?? 0;
        const totalCompactions = compactions?.totalCompactions ?? 0;
        const fromModelUsage = aggregateUsage.input_tokens +
            aggregateUsage.cache_read_input_tokens +
            aggregateUsage.cache_creation_input_tokens;
        const inputTokens = fromModelUsage > 0
            ? fromModelUsage
            : (tokens?.totalInput ?? 0) +
                (cache?.totalRead ?? 0) +
                (cache?.totalCreation ?? 0);
        const outputTokens = aggregateUsage.output_tokens > 0
            ? aggregateUsage.output_tokens
            : tokens?.totalOutput ?? 0;
        const benchmark = {
            timestamp: new Date().toISOString(),
            steps,
            totals: {
                totalCostUsd: totalCost,
                durationMs: totalDurationMs,
                inputTokens,
                outputTokens,
                numTurns: resultMessage?.num_turns ?? totalTurns,
                totalCompactions,
                totalCacheReadTokens: cache?.totalRead ?? 0,
                totalCacheCreation5mTokens: cache?.totalCreation5m ?? 0,
                totalCacheCreation1hTokens: cache?.totalCreation1h ?? 0,
            },
        };
        this.writeBenchmarkData(benchmark);
        return benchmark;
    }
    writeBenchmarkData(data) {
        try {
            (0, atomic_write_js_1.atomicWriteJSON)(this.outputPath, data, 0o600);
            (0, debug_1.logToFile)(`Benchmark data written to ${this.outputPath}`);
            (0, ui_1.getUI)().log.info(`${chalk_1.default.blue('●')} ${chalk_1.default.cyan(agent_interface_1.AgentSignals.BENCHMARK)} Results written to ${this.outputPath}`);
        }
        catch (error) {
            (0, debug_1.logToFile)('Failed to write benchmark data:', error);
        }
    }
}
exports.JsonWriterPlugin = JsonWriterPlugin;
