#!/usr/bin/env node

const { execSync } = require('child_process');
const path = require('path');
const fs = require('fs');

/**
 * Quality Gate - 质量门禁工具
 * 执行 TypeScript 编译检查和 ESLint 检查
 */
class QualityGate {
  constructor(nestjsBasePath) {
    this.nestjsBasePath = nestjsBasePath || '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest';
    this.stats = {
      tsErrors: 0,
      eslintErrors: 0,
      eslintWarnings: 0,
      filesChecked: 0
    };
  }

  /**
   * 运行所有质量检查
   */
  async run() {
    console.log('🚦 启动 Quality Gate 检查...\n');
    
    let passed = true;
    
    // TypeScript 编译检查
    console.log('📝 第1阶段：TypeScript 编译检查...');
    const tsResult = await this.checkTypeScript();
    if (!tsResult) {
      passed = false;
      console.log('   ❌ TypeScript 编译检查失败\n');
    } else {
      console.log('   ✅ TypeScript 编译检查通过\n');
    }
    
    // ESLint 检查
    console.log('📝 第2阶段：ESLint 代码规范检查...');
    const eslintResult = await this.checkESLint();
    if (!eslintResult) {
      passed = false;
      console.log('   ❌ ESLint 检查失败\n');
    } else {
      console.log('   ✅ ESLint 检查通过\n');
    }
    
    // 输出统计报告
    this.printStats();
    
    return passed;
  }

  /**
   * TypeScript 编译检查
   */
  async checkTypeScript() {
    try {
      console.log('   🔍 检查 TypeScript 类型...');
      
      // 运行 tsc --noEmit 进行类型检查
      const result = execSync('npm run type-check', {
        cwd: this.nestjsBasePath,
        encoding: 'utf8',
        stdio: 'pipe'
      });
      
      console.log('   ✅ TypeScript 类型检查通过');
      return true;
      
    } catch (error) {
      this.stats.tsErrors++;
      
      if (error.stdout) {
        console.error('   ❌ TypeScript 错误:');
        console.error(error.stdout);
      }
      
      if (error.stderr) {
        console.error(error.stderr);
      }
      
      return false;
    }
  }

  /**
   * ESLint 检查
   */
  async checkESLint() {
    try {
      console.log('   🔍 检查代码规范...');
      
      // 运行 ESLint
      const result = execSync('npm run lint', {
        cwd: this.nestjsBasePath,
        encoding: 'utf8',
        stdio: 'pipe'
      });
      
      console.log('   ✅ ESLint 检查通过');
      return true;
      
    } catch (error) {
      // ESLint 返回非零退出码表示有错误或警告
      if (error.stdout) {
        const output = error.stdout;
        
        // 解析错误和警告数量
        const errorMatch = output.match(/(\d+)\s+errors?/);
        const warningMatch = output.match(/(\d+)\s+warnings?/);
        
        if (errorMatch) {
          this.stats.eslintErrors = parseInt(errorMatch[1]);
        }
        
        if (warningMatch) {
          this.stats.eslintWarnings = parseInt(warningMatch[1]);
        }
        
        console.error('   ❌ ESLint 发现问题:');
        console.error(output);
        
        // 如果只有警告，不算失败
        return this.stats.eslintErrors === 0;
      }
      
      return false;
    }
  }

  /**
   * 检查单个文件
   */
  async checkFile(filePath) {
    console.log(`   🔍 检查文件: ${filePath}`);
    
    try {
      // 使用 tsc 检查单个文件
      execSync(`npx tsc --noEmit ${filePath}`, {
        cwd: this.nestjsBasePath,
        encoding: 'utf8',
        stdio: 'pipe'
      });
      
      // 使用 ESLint 检查单个文件
      execSync(`npx eslint ${filePath}`, {
        cwd: this.nestjsBasePath,
        encoding: 'utf8',
        stdio: 'pipe'
      });
      
      this.stats.filesChecked++;
      return true;
      
    } catch (error) {
      console.error(`   ❌ 文件检查失败: ${filePath}`);
      if (error.stdout) {
        console.error(error.stdout);
      }
      return false;
    }
  }

  /**
   * 快速检查（只检查核心层）
   */
  async quickCheck() {
    console.log('🚀 快速质量检查（仅核心层）...\n');
    
    const coreFiles = this.getGeneratedFiles();
    
    console.log(`   📁 发现 ${coreFiles.length} 个生成的文件\n`);
    
    let passed = 0;
    let failed = 0;
    
    for (const file of coreFiles) {
      const result = await this.checkFile(file);
      if (result) {
        passed++;
      } else {
        failed++;
      }
    }
    
    console.log(`\n📊 快速检查结果:`);
    console.log(`   ✅ 通过: ${passed}`);
    console.log(`   ❌ 失败: ${failed}`);
    
    return failed === 0;
  }

  /**
   * 获取所有生成的文件
   */
  getGeneratedFiles() {
    const coreDir = path.join(this.nestjsBasePath, 'src', 'core');
    const files = [];
    
    const scanDir = (dir) => {
      if (!fs.existsSync(dir)) return;
      
      const entries = fs.readdirSync(dir, { withFileTypes: true });
      
      for (const entry of entries) {
        const fullPath = path.join(dir, entry.name);
        
        if (entry.isDirectory()) {
          scanDir(fullPath);
        } else if (entry.name.endsWith('.ts') && !entry.name.endsWith('.d.ts')) {
          files.push(fullPath);
        }
      }
    };
    
    scanDir(coreDir);
    return files;
  }

  /**
   * 输出统计报告
   */
  printStats() {
    console.log('📊 Quality Gate 统计报告');
    console.log('==================================================');
    console.log(`   📝 TypeScript 错误: ${this.stats.tsErrors}`);
    console.log(`   📝 ESLint 错误: ${this.stats.eslintErrors}`);
    console.log(`   ⚠️  ESLint 警告: ${this.stats.eslintWarnings}`);
    console.log(`   📁 检查文件数: ${this.stats.filesChecked}`);
    console.log('==================================================');
    
    const passed = this.stats.tsErrors === 0 && this.stats.eslintErrors === 0;
    
    if (passed) {
      console.log('\n✅ 🎉 所有质量检查通过！');
    } else {
      console.log('\n❌ 质量检查失败，请修复上述问题');
      console.log('提示: 运行 "npm run lint:fix" 自动修复部分问题');
    }
    
    return passed;
  }
}

// 如果直接运行此文件
if (require.main === module) {
  const args = process.argv.slice(2);
  const mode = args[0] || 'full';
  
  const gate = new QualityGate();
  
  if (mode === 'quick') {
    gate.quickCheck().then(passed => {
      process.exit(passed ? 0 : 1);
    });
  } else {
    gate.run().then(passed => {
      process.exit(passed ? 0 : 1);
    });
  }
}

module.exports = QualityGate;

