import { appendFileSync, mkdirSync } from 'node:fs';
import { dirname } from 'node:path';
export class EvalProgressReporter {
    progressPath;
    caseId;
    writeStdout;
    constructor(args) {
        this.caseId = args.caseId;
        this.progressPath = args.progressPath;
        this.writeStdout = args.writeStdout ?? true;
        mkdirSync(dirname(this.progressPath), { recursive: true });
    }
    info(phase, message) {
        this.write({
            timestamp: new Date().toISOString(),
            caseId: this.caseId,
            phase,
            status: 'info',
            message,
        });
    }
    async track(args) {
        const startedAt = Date.now();
        this.write({
            timestamp: new Date(startedAt).toISOString(),
            caseId: this.caseId,
            phase: args.phase,
            status: 'started',
            message: args.message,
            elapsedMs: 0,
        });
        const heartbeatMs = args.heartbeatMs ?? 30_000;
        const interval = heartbeatMs > 0 ?
            setInterval(() => {
                const elapsedMs = Date.now() - startedAt;
                this.write({
                    timestamp: new Date().toISOString(),
                    caseId: this.caseId,
                    phase: args.phase,
                    status: 'heartbeat',
                    message: args.heartbeatMessage ?? `still running ${args.message}`,
                    elapsedMs,
                });
            }, heartbeatMs)
            : undefined;
        try {
            const result = await args.run();
            const elapsedMs = Date.now() - startedAt;
            this.write({
                timestamp: new Date().toISOString(),
                caseId: this.caseId,
                phase: args.phase,
                status: 'completed',
                message: args.message,
                elapsedMs,
            });
            return result;
        }
        catch (error) {
            const elapsedMs = Date.now() - startedAt;
            this.write({
                timestamp: new Date().toISOString(),
                caseId: this.caseId,
                phase: args.phase,
                status: 'failed',
                message: error instanceof Error ? error.message : String(error),
                elapsedMs,
            });
            throw error;
        }
        finally {
            if (interval) {
                clearInterval(interval);
            }
        }
    }
    write(event) {
        appendFileSync(this.progressPath, `${JSON.stringify(event)}\n`, 'utf8');
        if (this.writeStdout) {
            process.stdout.write(formatProgressLine(event));
        }
    }
}
function formatProgressLine(event) {
    const elapsed = event.elapsedMs === undefined ? '' : ` (${formatElapsed(event.elapsedMs)})`;
    return `[${event.caseId}] ${event.status}: ${event.message}${elapsed}\n`;
}
function formatElapsed(elapsedMs) {
    if (elapsedMs < 1000) {
        return `${elapsedMs}ms`;
    }
    return `${Math.round(elapsedMs / 1000)}s`;
}
//# sourceMappingURL=progress.js.map