import { describe, expect, it } from 'vitest';
import { MockLlm } from '../src/mock/mockLlm';
import { makeEvalSuiteRunner } from '../src/tier1/testExec';
import { counterfactualSubstrate, runVanillaJob } from '../src/tier1/vanilla';
import { buildRepoZip } from '../src/tier1/exportRepo';
import type { LlmCallRecord } from '../src/core/types';

describe('SET 13 vanilla run mode', () => {
  it('makes exactly ONE LLM call', async () => {
    const usage: LlmCallRecord[] = [];
    const llm = new MockLlm(u => usage.push(u));
    const res = await runVanillaJob({
      prompt: 'tiny greeter library',
      llm,
      runSuite: makeEvalSuiteRunner(),
    });
    expect(usage).toHaveLength(1);
    expect(usage[0]!.op).toBe('vanilla');
    expect(res.mode).toBe('vanilla');
    expect(res.metrics.freshDraws).toBe(1);
    expect(res.metrics.repairDraws).toBe(0);
    expect(res.files.length).toBeGreaterThan(0);
    expect(res.frozenTests.length).toBeGreaterThan(0);
  });

  it('counterfactual is computed with zero extra LLM calls', async () => {
    const usage: LlmCallRecord[] = [];
    const llm = new MockLlm(u => usage.push(u));
    const res = await runVanillaJob({
      prompt: 'tiny greeter library',
      llm,
      runSuite: makeEvalSuiteRunner(),
    });
    expect(usage).toHaveLength(1);
    expect(res.counterfactual).toBeDefined();
    expect(res.counterfactual.summary).toMatch(/substrate would have:/);

    // Pure dry-run helper also adds no calls
    const before = usage.length;
    const again = counterfactualSubstrate({
      prompt: 'x',
      spec: res.spec,
      files: res.files,
      tests: res.frozenTests,
      failures: [{ name: '__suite__', message: 'unresolved import ./missing (from src/greet)' }],
    });
    expect(usage).toHaveLength(before);
    expect(again.mechanicalWouldFix).toBeGreaterThanOrEqual(0);
    expect(again.classified).toBe(1);
  });

  it('supergit/export path still records the artifact', async () => {
    const res = await runVanillaJob({
      prompt: 'tiny greeter library',
      llm: new MockLlm(),
      runSuite: makeEvalSuiteRunner(),
    });
    const zip = await buildRepoZip(res);
    expect(zip.byteLength).toBeGreaterThan(100);
  });

  it('referee cost bucket field is present (null when unused)', async () => {
    const res = await runVanillaJob({
      prompt: 'tiny greeter library',
      llm: new MockLlm(),
      runSuite: makeEvalSuiteRunner(),
    });
    expect(res).toHaveProperty('refereeCostUsd');
    expect(res.refereeCostUsd).toBeNull();
  });
});
