/**
 * Emit the passive corpus as versioned static JSON under web/public/corpus/v1/.
 *
 * The Pages site (rha.software) serves these files; the extension's Tier 1
 * runner fetches them and drives the user's own LLM through the pipeline.
 * The corpus is data only — system prompts, algorithm bounds, lessons. The
 * user-prompt assembly functions stay code and ship inside the runner bundle.
 *
 * manifest.json carries a sha256 per file so a consumer can verify integrity
 * and cache by content.
 */
import { createHash } from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import {
  BUILD_SYSTEM,
  ENCODE_SYSTEM,
  FEATURE_ENUM_SYSTEM,
  FEATURE_PROBE_SYSTEM,
  FEATURE_REPAIR_SYSTEM,
  HARNESS_CONTRACT_SYSTEM,
  IR_CASE_FIX_SYSTEM,
  IR_SYSTEM,
  RHA_SYSTEM,
  STUB_FIX_SYSTEM,
} from '../src/core/prompts';
import { corpusBaseline } from '../src/core/config';
import { loadLessons } from '../src/core/lessons';
import { VERSION } from '../src/version';
import { TESTGEN_TEMPLATES } from '../src/tier1/testgenOracle.generated';
import { REPAIR_ORACLE } from '../src/tier1/repairOracle.generated';

const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
export const DEFAULT_OUT_DIR = path.join(ROOT, 'web', 'public', 'corpus', 'v1');

export interface CorpusManifest {
  corpusVersion: 1;
  appVersion: string;
  generatedAt: string;
  files: { name: string; sha256: string; bytes: number }[];
}

/** System prompts keyed by pipeline stage, in pipeline order. */
export function corpusPrompts(): Record<string, string> {
  return {
    featureEnum: FEATURE_ENUM_SYSTEM,
    featureProbe: FEATURE_PROBE_SYSTEM,
    encode: ENCODE_SYSTEM,
    featureRepair: FEATURE_REPAIR_SYSTEM,
    stubFix: STUB_FIX_SYSTEM,
    ir: IR_SYSTEM,
    irCaseFix: IR_CASE_FIX_SYSTEM,
    build: BUILD_SYSTEM,
    rha: RHA_SYSTEM,
    harnessContract: HARNESS_CONTRACT_SYSTEM,
  };
}

export function buildCorpus(outDir = DEFAULT_OUT_DIR): CorpusManifest {
  fs.mkdirSync(outDir, { recursive: true });

  const payloads: Record<string, string> = {
    'prompts.json': JSON.stringify({ stages: corpusPrompts() }, null, 2),
    'gates.json': JSON.stringify(corpusBaseline(), null, 2),
    'lessons.json': JSON.stringify({ lessons: loadLessons() }, null, 2),
    'testgen-oracle.json': JSON.stringify({ templates: TESTGEN_TEMPLATES }, null, 2),
    'repair-oracle.json': JSON.stringify({ entries: REPAIR_ORACLE }, null, 2),
  };

  const files: CorpusManifest['files'] = [];
  for (const [name, content] of Object.entries(payloads)) {
    fs.writeFileSync(path.join(outDir, name), content);
    files.push({
      name,
      sha256: createHash('sha256').update(content).digest('hex'),
      bytes: Buffer.byteLength(content),
    });
  }

  const manifest: CorpusManifest = {
    corpusVersion: 1,
    appVersion: VERSION,
    generatedAt: new Date().toISOString(),
    files,
  };
  fs.writeFileSync(path.join(outDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
  return manifest;
}

const invokedDirectly =
  process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
if (invokedDirectly) {
  const manifest = buildCorpus();
  // eslint-disable-next-line no-console
  console.log(`corpus v1 written to ${DEFAULT_OUT_DIR} (${manifest.files.length} files, app ${manifest.appVersion})`);
}
