import { readdirSync, readFileSync, statSync } from 'fs';
import { join, relative } from 'path';

const ROOT = process.cwd();
const TARGETS = [
  join(ROOT, 'app'),
  join(ROOT, 'lib', 'actions.ts'),
  join(ROOT, 'lib', 'modules'),
];

const EXCLUDED_DIRS = new Set(['node_modules', '.next', '.git', 'dist', 'build']);
const EXCLUDED_SUFFIXES = ['.md', '.txt', '.json'];
const ALLOWED_PATH_HINTS = [
  'scripts/seed-postgres-from-json.ts',
  'scripts/audit-json-runtime-usage.ts',
  'tests/',
  '__tests__',
];

const importPattern = /from\s+['\"](?:@\/lib\/data|\.\/data|\.\.\/data)['\"]/g;

function shouldSkip(filePath: string): boolean {
  const normalized = filePath.replace(/\\/g, '/');
  if (EXCLUDED_SUFFIXES.some((suffix) => normalized.endsWith(suffix))) return true;
  if (ALLOWED_PATH_HINTS.some((hint) => normalized.includes(hint))) return true;
  return false;
}

function walk(path: string, files: string[]): void {
  const st = statSync(path);
  if (st.isDirectory()) {
    const name = path.split(/[/\\]/).pop() || '';
    if (EXCLUDED_DIRS.has(name)) return;
    for (const entry of readdirSync(path)) {
      walk(join(path, entry), files);
    }
    return;
  }
  files.push(path);
}

const allFiles: string[] = [];
for (const target of TARGETS) {
  try {
    walk(target, allFiles);
  } catch {
    // Ignore missing targets in partial environments
  }
}

const violations: Array<{ file: string; type: 'import' | 'call'; snippet: string }> = [];

for (const file of allFiles) {
  if (shouldSkip(file)) continue;
  const rel = relative(ROOT, file).replace(/\\/g, '/');
  const content = readFileSync(file, 'utf-8');

  const importMatches = content.match(importPattern) || [];
  if (importMatches.length > 0) {
    violations.push({ file: rel, type: 'import', snippet: importMatches[0] });
  }

}

if (violations.length === 0) {
  console.log('PASS: No JSON runtime usage detected in guarded targets.');
  process.exit(0);
}

console.error('FAIL: JSON runtime usage detected.');
for (const v of violations) {
  console.error(`- [${v.type}] ${v.file}: ${v.snippet}`);
}
process.exit(1);
