#!/usr/bin/env node
/**
 * enforce-mentor-then-judge — оркестратор строгой последовательности «наставник → судья».
 * Заменяет ДВА параллельных PostToolUse Write-хука одним: наставник до конца, ПОТОМ судья
 * (читает свежий mentor-GO/вердикт). Машины enforce-mentor-on-plan-write / enforce-judge-gate
 * НЕ меняются — запускаются как дочерние процессы последовательно, событие в stdin.
 * Регистрация (один блок вместо двух) — шаг владельца.
 */
import { readStdin, exitDecision } from './enforce-hook-helpers.mjs';
import { spawn } from 'node:child_process';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
export const MENTOR_HOOK = join(__dirname, 'enforce-mentor-on-plan-write.mjs');
export const JUDGE_HOOK = join(__dirname, 'enforce-judge-gate.mjs');

/**
 * Запустить хук-процесс, передать событие в stdin, вернуть {code, stderr}.
 * Протокол (exitDecision): block → stderr + exit 2; allow → stdout '{}' + exit 0.
 * stdout дочки гасим (не льём в свой stdout). Не смог запуститься → code 0 (producer fail-safe).
 */
export function spawnHookProc(scriptPath, eventJson) {
  return new Promise((resolve) => {
    let ch;
    try { ch = spawn(process.execPath, [scriptPath], { stdio: ['pipe', 'pipe', 'pipe'] }); }
    catch { resolve({ code: 0, stderr: '' }); return; }
    let stderr = '';
    ch.stderr.on('data', (d) => { stderr += String(d); });
    ch.on('close', (code) => resolve({ code: code == null ? 0 : code, stderr: stderr.trim() }));
    ch.on('error', () => resolve({ code: 0, stderr: '' }));
    try { ch.stdin.write(eventJson); ch.stdin.end(); } catch { /* дочка закрыла stdin */ }
  });
}

/**
 * Чистое ядро: наставник ДО КОНЦА, потом судья (строго после, свежий mentor-GO/вердикт).
 * Наставник exit-2 → block с его stderr, судья НЕ запускается (круг L1 первым). Наставник
 * allow (любой не-2 код — producer fail-safe) → судья запускается, его решение наружу.
 */
export async function runMentorThenJudge(eventJson, { spawnHook } = {}) {
  const m = await spawnHook(MENTOR_HOOK, eventJson);
  if (m && m.code === 2) return { block: true, message: m.stderr };
  const j = await spawnHook(JUDGE_HOOK, eventJson);
  return { block: !!(j && j.code === 2), message: (j && j.code === 2) ? j.stderr : undefined };
}

async function main() {
  try {
    const raw = await readStdin();
    const r = await runMentorThenJudge(raw, { spawnHook: spawnHookProc });
    exitDecision({ block: r.block, message: r.block ? r.message : undefined });
  } catch {
    exitDecision({ block: false }); // обёртка-оркестратор никогда не кирпичит на своей ошибке
  }
}

const isCli = process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1];
if (isCli) main();
