/**
 * Part U3 — scaffolding-integrity guard.
 * On re-entry, verify workspace against freeze hashes (+ optional code digests
 * recorded in the last build). External edits → warn, do not silently proceed.
 */
import fs from 'node:fs';
import path from 'node:path';
import type { IRManifest } from './types';
import { sha256 } from './sandbox';

export interface ScaffoldCheck {
  ok: boolean;
  /** True when freeze hashes or recorded digests diverge from disk. */
  externalEdits: boolean;
  mismatches: { path: string; reason: string }[];
  message?: string;
}

export function checkScaffoldingIntegrity(
  dir: string,
  manifest: IRManifest | null | undefined,
): ScaffoldCheck {
  if (!manifest?.freezeHashes || !Object.keys(manifest.freezeHashes).length) {
    return { ok: true, externalEdits: false, mismatches: [] };
  }
  const mismatches: { path: string; reason: string }[] = [];
  for (const [file, hash] of Object.entries(manifest.freezeHashes)) {
    const abs = path.join(dir, file);
    if (!fs.existsSync(abs)) {
      mismatches.push({ path: file, reason: 'missing frozen suite' });
      continue;
    }
    const actual = sha256(fs.readFileSync(abs, 'utf8'));
    if (actual !== hash) {
      mismatches.push({ path: file, reason: 'freeze hash mismatch — external edit or tamper' });
    }
  }
  // Ledger presence is part of the scaffolding chain.
  const ledger = path.join(dir, '.supergit', 'ledger.csv');
  if (!fs.existsSync(ledger)) {
    mismatches.push({ path: '.supergit/ledger.csv', reason: 'ledger missing' });
  }

  if (!mismatches.length) {
    return { ok: true, externalEdits: false, mismatches: [] };
  }
  return {
    ok: false,
    externalEdits: true,
    mismatches,
    message:
      'scaffolding interrupted — external edits detected. Reconcile (restore from ledger) or fork a new job rather than continuing silently.',
  };
}
