#!/usr/bin/env node
/**
 * One-shot retrofill: add primary_rationale.chain_ref to existing v2 episodes
 * in docs/observer/episodes-*.jsonl. Idempotent (skips lines that already have
 * chain_ref), atomic per file (tmp + rename). Pure fs, no LLM.
 *
 * Usage: node tools/observer-retrofill-chain-ref.mjs [--dry-run]
 */
import { readFileSync, writeFileSync, renameSync, readdirSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { loadChainMap, chainsFor } from './observer-chain-detector.mjs';

const __dirname = dirname(fileURLToPath(import.meta.url));
const OBS_DIR = join(__dirname, '..', 'docs', 'observer');

/** Add chain_ref to a single parsed episode object (pure). Idempotent. */
export function retrofillLine(ep, map) {
  if (!ep || ep.schema_version !== 2 || !ep.primary_rationale) return ep;
  if ('chain_ref' in ep.primary_rationale) return ep; // idempotent
  ep.primary_rationale.chain_ref = chainsFor(ep.primary_rationale.node_chosen, map);
  return ep;
}

/** Process one JSONL file atomically (tmp + rename). Returns {changed, total}. */
export function retrofillFile(path, map, { dryRun = false } = {}) {
  const lines = readFileSync(path, 'utf8').split(/\r?\n/);
  let changed = 0;
  let total = 0;
  const out = lines.map((line) => {
    if (!line.trim()) return line;
    total++;
    const ep = JSON.parse(line);
    const before = ep.primary_rationale && 'chain_ref' in ep.primary_rationale;
    const next = retrofillLine(ep, map);
    const after = next.primary_rationale && 'chain_ref' in next.primary_rationale;
    if (!before && after) changed++;
    return JSON.stringify(next);
  });
  if (!dryRun && changed > 0) {
    const tmp = `${path}.tmp`;
    writeFileSync(tmp, out.join('\n'), 'utf8');
    renameSync(tmp, path);
  }
  return { changed, total };
}

function main() {
  const dryRun = process.argv.includes('--dry-run');
  const map = loadChainMap();
  const files = readdirSync(OBS_DIR).filter((f) => /^episodes-\d{4}-\d{2}\.jsonl$/.test(f));
  for (const f of files) {
    const { changed, total } = retrofillFile(join(OBS_DIR, f), map, { dryRun });
    console.log(`${dryRun ? '[dry-run] ' : ''}${f}: ${changed}/${total} lines get chain_ref`);
  }
}

if (process.argv[1]?.endsWith('observer-retrofill-chain-ref.mjs')) main();
