import { describe, expect, it, beforeEach, afterEach } from 'vitest';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import {
  appendLesson,
  loadLessons,
  resetLessonsCache,
} from '../src/core/lessons';
import { applyLessonFix } from '../src/core/diagnostics';
import type { TscDiagnostic } from '../src/core/sandbox';

describe('cross-run lessons', () => {
  let tmp: string;
  let file: string;

  beforeEach(() => {
    tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'rha-crossrun-'));
    file = path.join(tmp, 'lessons.jsonl');
    resetLessonsCache();
  });

  afterEach(() => {
    resetLessonsCache();
    fs.rmSync(tmp, { recursive: true, force: true });
  });

  it('reload lessons → same idiom resolves with zero LLM calls', () => {
    appendLesson({
      classKey: 'TS2305|src/api.ts|fetchThing',
      idiom: 'TS2305: suite imports member fetchThing absent from src/api.ts',
      resolution: 'additive widen',
      member: 'fetchThing',
      target: 'src/api.ts',
      signature: `export function fetchThing(..._args: unknown[]): never { throw new Error('stub: not implemented'); }`,
      ts: new Date().toISOString(),
    }, file);

    // Simulate restart
    resetLessonsCache();
    loadLessons(file);

    const d: TscDiagnostic = {
      file: 'tests/x.test.ts',
      line: 4,
      code: 2305,
      message: `Module '"./api"' has no exported member 'fetchThing'.`,
    };
    let llm = 0;
    let content = 'export {}\n';
    const next = applyLessonFix(d, content);
    if (!next) llm++;
    else content = next;

    expect(llm).toBe(0);
    expect(content).toContain('fetchThing');
  });
});
