#!/usr/bin/env npx tsx
/**
 * Privacy contract guard (ML01 §1.2).
 * Scans every compiled JS/JSX/TSX file under src/ for vendor-name strings that must
 * never reach the customer-facing UI. Fails with a non-zero exit code on any match.
 *
 * Usage (add to CI):
 *   npx tsx scripts/check-vendor-leak.ts
 *
 * Exception: lines that contain the literal comment "privacy-ok" are skipped, allowing
 * forms like "Bring your own OpenAI key" in customer-supplied label copy.
 */

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

const VENDOR_TERMS = [
  'openai',
  'anthropic',
  'claude',
  'gpt-5',
  'gpt-4',
  'gpt-3',
  'ollama',
  'mistral',
  'llama',
  'groq',
  'azure-openai',
  'together',
  'perplexity',
  'featherless',
  'vertex',
  'bedrock',
];

const VENDOR_RE = new RegExp(`\\b(${VENDOR_TERMS.join('|')})\\b`, 'i');

const SCAN_DIRS = ['src/components', 'src/app', 'src/lib'];
const EXTENSIONS = new Set(['.tsx', '.ts', '.jsx', '.js']);
const ROOT = join(import.meta.dirname ?? process.cwd(), '..');

function walk(dir: string): string[] {
  const paths: string[] = [];
  for (const entry of readdirSync(dir)) {
    const full = join(dir, entry);
    const st = statSync(full);
    if (st.isDirectory()) {
      paths.push(...walk(full));
    } else if (EXTENSIONS.has(entry.slice(entry.lastIndexOf('.')))) {
      paths.push(full);
    }
  }
  return paths;
}

let totalViolations = 0;

for (const scanDir of SCAN_DIRS) {
  const absDir = join(ROOT, scanDir);
  let files: string[];
  try {
    files = walk(absDir);
  } catch {
    continue;
  }

  for (const file of files) {
    const content = readFileSync(file, 'utf8');
    const lines = content.split('\n');
    for (let i = 0; i < lines.length; i++) {
      const line = lines[i];
      if (line.includes('privacy-ok')) continue;
      if (line.includes('sanitizeEngineLogForDisplay')) continue;
      if (line.includes('VENDOR_LEAK_RE') || line.includes('VENDOR_TERMS')) continue;
      if (VENDOR_RE.test(line)) {
        console.error(`PRIVACY LEAK: ${relative(ROOT, file)}:${i + 1}`);
        console.error(`  ${line.trim()}`);
        totalViolations++;
      }
    }
  }
}

if (totalViolations > 0) {
  console.error(`\n${totalViolations} privacy violation(s) found. Remove vendor identifiers from customer-facing code.`);
  process.exit(1);
} else {
  console.log('Privacy check passed — no vendor identifiers found in customer-facing code.');
}
