import { describe, expect, it } from 'vitest';
import { runTier1Job } from '../src/tier1/runner';
import { buildTestProgram, makeEvalSuiteRunner } from '../src/tier1/testExec';
import { MockLlm } from '../src/mock/mockLlm';

describe('tier 1 authenticate + RHA (the complete algorithm, in memory)', () => {
  it('executes frozen suites, localizes the injected bugs, and heals them', async () => {
    const events: { phase: string; featureId: string | null; message: string }[] = [];
    const res = await runTier1Job({
      prompt: 'URL shortener library',
      llm: new MockLlm(),
      runSuite: makeEvalSuiteRunner(),
      onEvent: e => events.push(e),
    });

    // The mock fixture ships 3 injected bugs — authenticate MUST see failures
    // and RHA must run. If auth never fails, the harness proved nothing.
    expect(events.some(e => e.phase === 'rha')).toBe(true);

    // Converged: no unresolved problems; artifact heals to green.
    expect(res.problems).toEqual([]);

    // Every suite passes against the final artifact — re-verify from scratch.
    const run = makeEvalSuiteRunner();
    for (const t of res.frozenTests) {
      const r = await run(res.files, t);
      expect(r.crashed, `${t.path} crashed`).toBeUndefined();
      expect(r.total).toBeGreaterThan(0);
      expect(r.failures, `${t.path} failures`).toEqual([]);
    }
  });

  it('honestly reports an unauthenticated artifact when no runner exists', async () => {
    const res = await runTier1Job({ prompt: 'URL shortener library', llm: new MockLlm() });
    expect(res.problems.some(p => p.includes('not authenticated'))).toBe(true);
  });

  it('builds a self-contained program that reports failures without crashing the host', async () => {
    const files = [{ path: 'src/adder.ts', content: 'export function add(a: number, b: number): number { return a - b; }' }];
    const test = {
      path: 'tests/adder.test.ts',
      content: [
        "import { describe, it, expect } from 'vitest';",
        "import { add } from '../src/adder';",
        "describe('adder', () => {",
        "  it('adds', () => { expect(add(2, 3)).toBe(5); });",
        "  it('identity', () => { expect(add(7, 0)).toBe(7); });",
        '});',
      ].join('\n'),
    };
    const program = buildTestProgram(files, test);
    expect(program).toContain('__RHA_RUN__');
    const run = makeEvalSuiteRunner();
    const r = await run(files, test);
    expect(r.total).toBe(2);
    expect(r.failures.length).toBe(1);
    expect(r.failures[0].name).toContain('adds');
    expect(r.failures[0].message).toContain('toBe');
  });
});
