import { mkdirSync } from 'node:fs';
import { join, resolve } from 'node:path';
import { collectEvalArtifacts, writeTextArtifact } from './git-artifacts.js';
import { prepareEvalWorkspace } from './workspace-fixture.js';
import { runEvalChecks } from './check-runner.js';
import { runCommand } from './process.js';
import { EvalProgressReporter } from './progress.js';
import { analyzeTraceFiles } from './trace-analyzer.js';
export async function runAgentEvalCase(args) {
    const startedAtMs = Date.now();
    const startedAt = new Date(startedAtMs).toISOString();
    const target = args.target ?? 'current';
    const outputDir = join(args.resultsRoot, target, args.testCase.id);
    mkdirSync(outputDir, { recursive: true });
    const progress = new EvalProgressReporter({
        caseId: args.testCase.id,
        progressPath: join(outputDir, 'progress.jsonl'),
    });
    progress.info('case', 'starting eval case');
    try {
        const prepared = await progress.track({
            phase: 'workspace.prepare',
            message: 'prepare eval workspace',
            heartbeatMessage: 'still preparing eval workspace',
            run: () => prepareEvalWorkspace({
                testCase: args.testCase,
                repoRoot: args.repoRoot,
                workRoot: args.workRoot ? resolve(args.workRoot) : undefined,
                progress,
            }),
        });
        const workspaceRoot = prepared.workspaceRoot;
        const model = args.model ?? args.testCase.model;
        const maxSteps = args.maxSteps ?? args.testCase.maxSteps;
        const command = buildHeddleAskCommand({
            workspaceRoot,
            model,
            maxSteps,
            prompt: args.testCase.prompt,
            sessionName: `eval-${args.testCase.id}`,
            preferApiKey: args.preferApiKey,
        });
        const stdoutPath = join(outputDir, 'stdout.txt');
        const stderrPath = join(outputDir, 'stderr.txt');
        const agentResult = args.dryRun ?
            {
                command,
                exitCode: 0,
                stdout: `Dry run: ${command.join(' ')}\n`,
                stderr: '',
                durationMs: 0,
                timedOut: false,
            }
            : await progress.track({
                phase: 'agent.run',
                message: 'run Heddle agent',
                heartbeatMessage: 'still running Heddle agent',
                run: () => runCommand({
                    command: command[0] ?? 'yarn',
                    args: command.slice(1),
                    cwd: args.repoRoot,
                    env: {
                        ...process.env,
                        HEDDLE_EVAL_AUTO_APPROVE: '1',
                    },
                    timeoutMs: args.timeoutMs ?? 15 * 60_000,
                }),
            });
        progress.info('agent.stdout', `write agent stdout to ${stdoutPath}`);
        writeTextArtifact(stdoutPath, agentResult.stdout);
        progress.info('agent.stderr', `write agent stderr to ${stderrPath}`);
        writeTextArtifact(stderrPath, agentResult.stderr);
        const checks = args.dryRun ? [] : await progress.track({
            phase: 'checks',
            message: 'run deterministic checks',
            heartbeatMessage: 'still running deterministic checks',
            run: () => runEvalChecks({
                checks: args.testCase.checks,
                workspaceRoot,
                progress,
            }),
        });
        const artifacts = await progress.track({
            phase: 'artifacts',
            message: 'collect eval artifacts',
            run: () => collectEvalArtifacts({
                workspaceRoot,
                outputDir,
                stateDir: args.stateDir,
            }),
        });
        const metrics = analyzeTraceFiles(artifacts.traceFiles);
        const finishedAtMs = Date.now();
        const status = agentResult.exitCode === 0
            && !agentResult.timedOut
            && checks.every((check) => check.passed) ?
            'passed'
            : 'failed';
        const result = {
            caseId: args.testCase.id,
            target,
            status,
            workspaceRoot,
            outputDir,
            fixture: prepared.fixture,
            startedAt,
            finishedAt: new Date(finishedAtMs).toISOString(),
            durationMs: finishedAtMs - startedAtMs,
            agent: {
                command,
                exitCode: agentResult.exitCode,
                stdoutPath,
                stderrPath,
                timedOut: agentResult.timedOut,
            },
            artifacts: {
                ...artifacts,
                progressPath: progress.progressPath,
            },
            checks,
            metrics,
            review: args.testCase.review,
            model,
            maxSteps,
        };
        progress.info('case', `completed eval case with status ${status}`);
        writeTextArtifact(join(outputDir, 'result.json'), `${JSON.stringify(result, null, 2)}\n`);
        return result;
    }
    catch (error) {
        progress.info('case', `eval case failed: ${error instanceof Error ? error.message : String(error)}`);
        throw error;
    }
}
export function buildHeddleAskCommand(args) {
    return [
        'yarn',
        'cli:dev',
        '--cwd',
        args.workspaceRoot,
        '--force-owner-conflict',
        ...(args.model ? ['--model', args.model] : []),
        ...(args.maxSteps ? ['--max-steps', String(args.maxSteps)] : []),
        ...(args.preferApiKey ? ['--prefer-api-key'] : []),
        'ask',
        '--new-session',
        args.sessionName,
        args.prompt,
    ];
}
//# sourceMappingURL=agent-runner.js.map