/**
 * TDD-gate real-test verification — router-gate v4 spec §3.11.
 * Pure ядро + тонкая fs-обёртка. Закрывает sentinel-gaming (touch test без expect/it).
 *
 * DEVIATION: spec §3.11 показывает @babel/parser AST. Babel не установлен —
 * regex-based extraction per спек note "basic regex + import check; AST refinement future".
 */
import fs from 'node:fs';
import path from 'node:path';

export function extractImportsAndStrings(content) {
  const out = [];
  // import ... from '<x>'
  for (const m of content.matchAll(/from\s+['"]([^'"]+)['"]/g)) out.push(m[1]);
  // require('<x>')
  for (const m of content.matchAll(/require\(\s*['"]([^'"]+)['"]\s*\)/g)) out.push(m[1]);
  // any string literals (single or double quoted)
  // NOTE: import paths captured above are also matched here; duplicates are harmless for the downstream .some() check.
  for (const m of content.matchAll(/['"]([^'"\n]+)['"]/g)) out.push(m[1]);
  return out;
}

export function verifyRealTestContent(content, editedFilesList) {
  const src = String(content || '');
  if (!/\bexpect\s*\(/.test(src)) return { valid: false, reason: 'no_expect_call' };
  if (!/\b(test|it)\s*\(/.test(src)) return { valid: false, reason: 'no_test_block' };

  const list = editedFilesList || [];
  if (list.length === 0) return { valid: true }; // no prod files to cover

  const strings = extractImportsAndStrings(src);
  const hasRelevant = list.some((editedFile) => {
    const base = path.basename(editedFile, path.extname(editedFile));
    // KNOWN: basename substring match can false-positive for short basenames (e.g. 'User' matched inside 'CurrentUser').
    // Acceptable at regex-approximation fidelity; AST refinement deferred (§3.11).
    return strings.some((s) => s.includes(base));
  });
  if (!hasRelevant) return { valid: false, reason: 'no_coverage_of_edited_files' };
  return { valid: true };
}

export function verifyRealTest(testFilePath, editedFilesList, opts = {}) {
  const { readFile = fs.readFileSync } = opts;
  let content;
  try {
    content = readFile(testFilePath, 'utf8');
  } catch (err) {
    const reason = err && err.code === 'ENOENT' ? 'test_file_not_found' : 'test_file_read_error';
    return { valid: false, reason };
  }
  return verifyRealTestContent(content, editedFilesList);
}
