import { logger } from '../../utils/logger';
import { SemanticLogService } from '../telemetry/SemanticLogService';
import fs from 'fs';
import path from 'path';

/**
 * [BIZ_KER_114] 自动化 SQL 注入防御扫描 (SQL Injection)
 * @description 核心逻辑：静态分析代码中的 SQL 拼接风险。
 * 扫描指定目录下的 .ts 文件，识别非参数化的 SQL 查询。
 * 联动语义日志中心生成安全扫描报告。
 */
export class SecurityScanService {
  private static readonly SCAN_TARGETS = [
    path.join(__dirname, '../../domains'),
    path.join(__dirname, '../../api/controllers')
  ];

  /**
   * 初始化扫描任务
   */
  static async init() {
    this.runScan();
    setInterval(() => this.runScan(), 24 * 60 * 60 * 1000); // 每日扫描
    logger.info(`[SecurityScan] SQL Injection defense scanner initialized`);
  }

  /**
   * 执行静态代码扫描
   */
  private static async runScan() {
    try {
      const report = await this.scanFiles();
      await SemanticLogService.logSemantic(report, 'INFO', 'SECURITY_SCAN');
      logger.info(`[SecurityScan] Daily scan report generated`);
    } catch (err: any) {
      logger.error(`[SecurityScan] Scan failed: ${err.message}`);
    }
  }

  /**
   * 递归扫描文件并分析内容
   */
  private static async scanFiles(): Promise<string> {
    let report = `### 🛡️ SQL Injection Security Audit (Static Analysis)\n\n`;
    let vulnerabilities: string[] = [];

    const walk = (dir: string) => {
      const files = fs.readdirSync(dir);
      for (const file of files) {
        const fullPath = path.join(dir, file);
        const stats = fs.statSync(fullPath);
        if (stats.isDirectory()) {
          walk(fullPath);
        } else if (file.endsWith('.ts')) {
          const content = fs.readFileSync(fullPath, 'utf8');
          const vulns = this.analyzeContent(content, file);
          vulnerabilities.push(...vulns);
        }
      }
    };

    this.SCAN_TARGETS.forEach(target => {
      if (fs.existsSync(target)) walk(target);
    });

    if (vulnerabilities.length > 0) {
      report += `**🚨 Found ${vulnerabilities.length} Potential SQL Injection Risks:**\n`;
      vulnerabilities.forEach(v => report += `- ${v}\n`);
      report += `\n**Optimization Advice:** 请始终使用 Knex 参数化查询 (\`where({ id: val })\` 或 \`raw('?...', [val])\`)，严禁使用模板字符串直接拼接 SQL 变量。\n`;
    } else {
      report += `**✅ No raw SQL string interpolation detected in monitored files.**\n`;
    }

    return report;
  }

  /**
   * 分析文件内容中的 SQL 拼接模式
   */
  private static analyzeContent(content: string, filename: string): string[] {
    const risks: string[] = [];
    // 识别常见危险模式：raw(`...${var}...`) 或 query(`...${var}...`)
    const rawPattern = /db\.raw\(`.*?\$\{.*?\}.*?`\)/g;
    const knexPattern = /db\(.*?\)\.whereRaw\(`.*?\$\{.*?\}.*?`\)/g;

    const rawMatches = content.match(rawPattern);
    const knexMatches = content.match(knexPattern);

    if (rawMatches) {
      rawMatches.forEach(m => risks.push(`[${filename}] Potential raw SQL interpolation: \`${m.substring(0, 50)}...\``));
    }
    if (knexMatches) {
      knexMatches.forEach(m => risks.push(`[${filename}] Potential whereRaw interpolation: \`${m.substring(0, 50)}...\``));
    }

    return risks;
  }
}
