"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createOAuthTraceRecorder = void 0;
const sink_memory_1 = require("./sink-memory");
const sink_verbose_stdout_1 = require("./sink-verbose-stdout");
const redactor_1 = require("./redactor");
/**
 * Create a per-attempt recorder. Always wires:
 *  - memory sink (read via `snapshot()`)
 *  - verbose stdout sink (no-op when verbose=false)
 *  - optional file sink (Phase 8)
 *
 * All event data passes through the redactor before reaching any sink.
 */
function createOAuthTraceRecorder(options) {
    const now = options.now ?? Date.now;
    const start = now();
    const memory = (0, sink_memory_1.createMemorySink)();
    const verbose = (0, sink_verbose_stdout_1.createVerboseStdoutSink)({ enabled: options.verbose, out: options.verboseOut });
    const sinks = [memory, verbose];
    if (options.fileSink)
        sinks.push(options.fileSink);
    const phaseCounts = {};
    let lastPhase;
    function toErrorObj(err) {
        if (!err)
            return undefined;
        if (err instanceof Error) {
            return { message: err.message };
        }
        return { code: err.code, message: err.message };
    }
    return {
        record(phase, data, error) {
            const ts = now();
            const elapsedMs = ts - start;
            const redacted = data ? (0, redactor_1.redactJsonShallow)(data) : undefined;
            const event = {
                sessionId: options.sessionId,
                provider: options.provider,
                phase,
                ts,
                elapsedMs,
                data: redacted,
                error: toErrorObj(error),
            };
            phaseCounts[phase] = (phaseCounts[phase] ?? 0) + 1;
            lastPhase = phase;
            for (const sink of sinks) {
                try {
                    sink.write(event);
                }
                catch {
                    // Sinks must never throw out — drop on failure.
                }
            }
        },
        snapshot() {
            return memory.snapshot();
        },
        summary() {
            return {
                totalMs: now() - start,
                phaseCounts: { ...phaseCounts },
                lastPhase,
            };
        },
        async flush() {
            for (const sink of sinks) {
                if (sink.flush) {
                    try {
                        await sink.flush();
                    }
                    catch {
                        // ignore
                    }
                }
            }
        },
    };
}
exports.createOAuthTraceRecorder = createOAuthTraceRecorder;
//# sourceMappingURL=trace-recorder.js.map