/**
 * PreToolUse(Edit|Write) wrapper for tools/tdd-real-test-verifier.mjs.
 * Router-gate v4 spec §3.11.
 *
 * Blocks Edit/Write on a *.test.* / *.spec.* file when the proposed content
 * lacks expect() / it() OR doesn't reference any of the prod files edited
 * this session (the sentinel-gaming guard from spec §3.11).
 *
 * Fail-CLOSE: an internal error blocks (security-hook default).
 */
import { fileURLToPath } from 'url';
import { join } from 'path';
import { existsSync, readFileSync } from 'fs';
import {
  readStdin,
  parseEventJson,
  exitDecision,
  runtimeDir,
} from './enforce-hook-helpers.mjs';
import { verifyRealTestContent } from './tdd-real-test-verifier.mjs';

const TEST_FILE_RE = /\.(?:test|spec)\.[a-z0-9]+$/i;

function readEditedFiles(sessionId) {
  try {
    const p = join(runtimeDir(), `edited-files-${sessionId || 'unknown'}.json`);
    if (!existsSync(p)) return [];
    const j = JSON.parse(readFileSync(p, 'utf-8'));
    return Array.isArray(j.files) ? j.files : [];
  } catch { return []; }
}

export function decide({ filePath, content, editedFiles }) {
  const fp = String(filePath || '').split('\\').join('/');
  if (!TEST_FILE_RE.test(fp)) return { block: false, reason: null };
  const r = verifyRealTestContent(content, editedFiles || []);
  if (r.valid) return { block: false, reason: null };
  return { block: true, reason: r.reason };
}

async function main() {
  try {
    const raw = await readStdin();
    const event = parseEventJson(raw);
    if (event.tool_name !== 'Edit' && event.tool_name !== 'Write') {
      return exitDecision({ block: false });
    }
    const filePath = event.tool_input?.file_path || '';
    const content = event.tool_input?.content || event.tool_input?.new_string || '';
    const sessionId = event.session_id || 'unknown';
    const editedFiles = readEditedFiles(sessionId);
    const r = decide({ filePath, content, editedFiles });
    if (r.block) {
      return exitDecision({
        block: true,
        message: `[tdd-real-test-verifier] proposed test file fails real-test check: ${r.reason}. Write a test that asserts behaviour (expect + it/test) and references one of the edited prod files.`,
      });
    }
    return exitDecision({ block: false });
  } catch {
    return exitDecision({ block: true, message: '[tdd-real-test-verifier] внутренняя ошибка — fail-CLOSE' });
  }
}

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