/**
 * Hot-path perf writers — append-only NDJSON spool, no SQLite.
 *
 * Loaded from the CLI root `postAction` and from `events.ts` timing helpers.
 * Must stay free of `../sqlite.js` so ordinary commands never load node:sqlite
 * (which emits ExperimentalWarning on stderr).
 */
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { getPerfSpoolPath } from '../state.js';
import { localMachineId } from '../origin-machine.js';
let _spoolOverride = null;
let _disabled = false;
/** Test seam — pair with db._resetPerfDbForTest. */
export function _resetPerfSpoolForTest(spoolPath) {
    _spoolOverride = spoolPath === undefined ? null : spoolPath;
    _disabled = false;
}
export function resolveSpoolPath() {
    if (process.env.AGENTS_PERF_SPOOL)
        return process.env.AGENTS_PERF_SPOOL;
    if (_spoolOverride)
        return _spoolOverride;
    return getPerfSpoolPath();
}
function isDisabled() {
    if (_disabled)
        return true;
    const v = process.env.AGENTS_DISABLE_PERF;
    return v === '1' || v === 'true';
}
/** Short session id: first 8 chars (sessions.short_id shape). */
export function shortSessionId(sessionId) {
    if (!sessionId)
        return undefined;
    const cleaned = sessionId.replace(/^session_/, '');
    return cleaned.length >= 8 ? cleaned.slice(0, 8) : cleaned || undefined;
}
/**
 * Append one sample to the spool. Never throws. Never opens SQLite.
 */
export function recordSample(sample) {
    if (isDisabled())
        return;
    if (!sample.label || !Number.isFinite(sample.durationMs))
        return;
    try {
        const tsMs = sample.tsMs ?? Date.now();
        const sessionId = sample.sessionId;
        const sessionShort = sample.sessionShort ?? shortSessionId(sessionId);
        const machine = sample.machine ?? localMachineId();
        const hostname = sample.hostname ?? os.hostname();
        const line = JSON.stringify({
            ts_ms: tsMs,
            kind: sample.kind,
            label: sample.label,
            duration_ms: sample.durationMs,
            session_id: sessionId,
            session_short: sessionShort,
            agent: sample.agent,
            agent_version: sample.agentVersion,
            machine,
            hostname,
            actor: sample.actor,
            cwd: sample.cwd,
            cache: sample.cache,
            exit_code: sample.exitCode,
            status: sample.status,
            meta_json: sample.metaJson,
        });
        const spool = resolveSpoolPath();
        fs.mkdirSync(path.dirname(spool), { recursive: true, mode: 0o700 });
        fs.appendFileSync(spool, line + '\n', { mode: 0o600 });
    }
    catch {
        // Fail soft.
    }
}
