const fs = require('fs');
const path = require('path');

let results = {
  secrets: [],
  dynamicRequire: [],
  unsafeFs: [],
  noValidation: [],
  processExit: [],
  evalUsage: [],
  rawSqlInjection: [],
  pathTraversal: [],
};

function walk(dir) {
  const entries = fs.readdirSync(dir, { withFileTypes: true });
  for (const e of entries) {
    if (e.name.startsWith('.') || e.name === 'node_modules' || e.name === 'dist' || e.name === 'coverage') continue;
    const p = path.join(dir, e.name);
    if (e.isDirectory()) {
      walk(p);
    } else if (e.name.endsWith('.ts') && !e.name.includes('.test.')) {
      const content = fs.readFileSync(p, 'utf8');
      const lines = content.split('\n');
      const short = p.replace(/^.*[\\/]Fivo-Cell[\\/]/, '');

      for (let i = 0; i < lines.length; i++) {
        const l = lines[i];
        const ln = i + 1;

        // Hardcoded secrets
        if (l.match(/password\s*[:=]\s*['"`][^'"`]{3,}['"`]/i) && !l.includes('example') && !l.includes('//') && !l.includes('TODO')) {
          results.secrets.push(`${short}:${ln}: HARDCODED: ${l.trim().substring(0, 100)}`);
        }

        // Dynamic require from user input
        if (l.includes('require(') && (l.includes('req.query') || l.includes('req.body') || l.includes('req.params') || l.includes('args['))) {
          results.dynamicRequire.push(`${short}:${ln}: ${l.trim().substring(0, 120)}`);
        }

        // Unsafe file operations
        if ((l.includes('writeFileSync') || l.includes('unlinkSync') || l.includes('rmSync') || l.includes('mkdirSync')) && (l.includes('req.query') || l.includes('req.body') || l.includes('req.params'))) {
          results.unsafeFs.push(`${short}:${ln}: ${l.trim().substring(0, 120)}`);
        }

        // Process exit in non-CLI code
        if (l.includes('process.exit(') && !short.includes('cli') && !short.includes('validation') && !short.includes('setup') && !short.includes('watcher') && !short.includes('repl')) {
          results.processExit.push(`${short}:${ln}: ${l.trim().substring(0, 120)}`);
        }

        // Eval
        if (l.includes('eval(') && !l.includes('//')) {
          results.evalUsage.push(`${short}:${ln}: ${l.trim().substring(0, 120)}`);
        }

        // Raw SQL injection  
        if ((l.includes('.exec(') || l.includes('.prepare(') || l.includes('.run(')) && (l.includes('req.query') || l.includes('req.body') || l.includes('req.params')) && !l.includes('String(') && !l.includes('parseInt(') && !l.includes('parseFloat(') && !l.includes('Number(')) {
          results.rawSqlInjection.push(`${short}:${ln}: ${l.trim().substring(0, 150)}`);
        }

        // Path traversal
        if (l.includes('path.join(') && (l.includes('req.query') || l.includes('req.body') || l.includes('req.params')) && !l.includes('os.homedir') && !l.includes('process.cwd')) {
          results.pathTraversal.push(`${short}:${ln}: ${l.trim().substring(0, 150)}`);
        }
      }
    }
  }
}

walk('src');

console.log('=== HARCODED SECRETS ===');
results.secrets.forEach(s => console.log('  ' + s));
console.log('  Count: ' + results.secrets.length);

console.log('\n=== DYNAMIC REQUIRE FROM INPUT ===');
results.dynamicRequire.forEach(s => console.log('  ' + s));
console.log('  Count: ' + results.dynamicRequire.length);

console.log('\n=== UNSAFE FS WITH USER INPUT ===');
results.unsafeFs.forEach(s => console.log('  ' + s));
console.log('  Count: ' + results.unsafeFs.length);

console.log('\n=== PROCESS.EXIT IN NON-CLI ===');
results.processExit.forEach(s => console.log('  ' + s));
console.log('  Count: ' + results.processExit.length);

console.log('\n=== EVAL USAGE ===');
results.evalUsage.forEach(s => console.log('  ' + s));
console.log('  Count: ' + results.evalUsage.length);

console.log('\n=== RAW SQL INJECTION RISK ===');
results.rawSqlInjection.forEach(s => console.log('  ' + s));
console.log('  Count: ' + results.rawSqlInjection.length);

console.log('\n=== PATH TRAVERSAL ===');
results.pathTraversal.forEach(s => console.log('  ' + s));
console.log('  Count: ' + results.pathTraversal.length);

const total = results.secrets.length + results.dynamicRequire.length + results.unsafeFs.length + results.processExit.length + results.evalUsage.length + results.rawSqlInjection.length + results.pathTraversal.length;
console.log('\n========================================');
console.log('TOTAL SECURITY FINDINGS: ' + total);
if (total === 0) console.log('CLEAN — No security vulnerabilities found.');
