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

describe('tier 1 runner (in-memory pipeline, mock LLM)', () => {
  it('runs encode → IR → build → authenticate → RHA with no filesystem', async () => {
    const events: string[] = [];
    const res = await runTier1Job({
      prompt: 'URL shortener library',
      llm: new MockLlm(),
      runSuite: makeEvalSuiteRunner(),
      onEvent: e => events.push(`${e.phase}${e.featureId ? ':' + e.featureId : ''}`),
    });

    expect(res.problems).toEqual([]);
    expect(res.spec.features.length).toBeGreaterThan(0);

    // Every feature froze a suite before any implementation existed.
    expect(res.frozenTests.length).toBe(res.spec.features.length);
    for (const t of res.frozenTests) {
      expect(t.path.startsWith('tests/')).toBe(true);
      expect(t.content).toContain('describe(');
    }

    // Every owned file was built (mock returns real implementations).
    const ownedPaths = res.spec.features.flatMap(f => f.files);
    const filePaths = res.files.map(f => f.path);
    for (const p of ownedPaths) expect(filePaths).toContain(p);
    for (const f of res.files) {
      expect(f.content).not.toContain('stub: not implemented');
    }

    // Phase ordering: encode before ir, ir before build, build before auth, done last.
    expect(events[0]).toBe('encode');
    expect(events.at(-1)).toBe('done');
    expect(events.findIndex(e => e.startsWith('ir'))).toBeLessThan(events.findIndex(e => e.startsWith('build')));
    expect(events.findIndex(e => e.startsWith('build'))).toBeLessThan(events.findIndex(e => e.startsWith('auth')));
  });

  it('emits frozen suites usable as a standalone test artifact', async () => {
    const res = await runTier1Job({ prompt: 'URL shortener library', llm: new MockLlm(), runSuite: makeEvalSuiteRunner() });
    // Suites import from implementation paths that exist in the artifact.
    for (const t of res.frozenTests) {
      const imports = [...t.content.matchAll(/from '\.\.\/(src\/[^']+)'/g)].map(m => m[1]);
      for (const imp of imports) {
        expect(res.files.some(f => f.path === imp || f.path === `${imp}.ts`)).toBe(true);
      }
    }
  });
});
