#!/usr/bin/env node

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

/**
 * 基础生成器类
 * 提供通用的 dry-run、文件操作、日志等功能
 */
class BaseGenerator {
  constructor(generatorName = 'Generator') {
    this.generatorName = generatorName;
    
    // 从环境变量或参数读取配置
    this.dryRun = process.env.DRY_RUN === 'true' || process.argv.includes('--dry-run');
    this.verbose = process.env.VERBOSE === 'true' || process.argv.includes('--verbose');
    
    this.stats = {
      filesCreated: 0,
      filesUpdated: 0,
      filesSkipped: 0,
      errors: 0
    };
  }

  /**
   * 安全写入文件（支持 dry-run）
   */
  writeFile(filePath, content, description = '') {
    try {
      if (this.dryRun) {
        console.log(`   [DRY-RUN] Would create/update: ${filePath}`);
        if (this.verbose && description) {
          console.log(`             Description: ${description}`);
        }
        this.stats.filesCreated++;
        return true;
      }

      // 确保目录存在
      this.ensureDir(path.dirname(filePath));
      
      // 写入文件
      fs.writeFileSync(filePath, content, 'utf8');
      
      const action = fs.existsSync(filePath) ? 'Updated' : 'Created';
      console.log(`     ✅ ${action}: ${filePath}`);
      
      if (action === 'Created') {
        this.stats.filesCreated++;
      } else {
        this.stats.filesUpdated++;
      }
      
      return true;
    } catch (error) {
      console.error(`     ❌ Failed to write ${filePath}:`, error.message);
      this.stats.errors++;
      return false;
    }
  }

  /**
   * 确保目录存在
   */
  ensureDir(dirPath) {
    if (this.dryRun) {
      return;
    }
    
    if (!fs.existsSync(dirPath)) {
      fs.mkdirSync(dirPath, { recursive: true });
    }
  }

  /**
   * 读取文件（安全）
   */
  readFile(filePath) {
    try {
      if (!fs.existsSync(filePath)) {
        return null;
      }
      return fs.readFileSync(filePath, 'utf8');
    } catch (error) {
      console.error(`     ❌ Failed to read ${filePath}:`, error.message);
      return null;
    }
  }

  /**
   * 检查文件是否存在
   */
  fileExists(filePath) {
    return fs.existsSync(filePath);
  }

  /**
   * 日志输出
   */
  log(message, level = 'info') {
    const prefix = {
      'info': '   ℹ️ ',
      'success': '   ✅',
      'warning': '   ⚠️ ',
      'error': '   ❌',
      'debug': '   🔍'
    };
    
    if (level === 'debug' && !this.verbose) {
      return;
    }
    
    console.log(`${prefix[level] || '   '}${message}`);
  }

  /**
   * 输出统计信息
   */
  printStats(additionalStats = {}) {
    console.log('\n📊 Generation Statistics');
    console.log('==================================================');
    
    if (this.dryRun) {
      console.log('   🔍 DRY-RUN MODE - No files were actually modified');
    }
    
    console.log(`   📁 Files Created: ${this.stats.filesCreated}`);
    console.log(`   🔄 Files Updated: ${this.stats.filesUpdated}`);
    console.log(`   ⏭️  Files Skipped: ${this.stats.filesSkipped}`);
    console.log(`   ❌ Errors: ${this.stats.errors}`);
    
    // 输出额外的统计信息
    for (const [key, value] of Object.entries(additionalStats)) {
      console.log(`   📈 ${key}: ${value}`);
    }
    
    const total = this.stats.filesCreated + this.stats.filesUpdated;
    const successRate = total > 0 
      ? ((total / (total + this.stats.errors)) * 100).toFixed(2) 
      : '0.00';
    
    console.log(`   📊 Success Rate: ${successRate}%`);
    console.log('==================================================');
  }

  /**
   * kebab-case 转换
   */
  toKebabCase(str) {
    return String(str)
      .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
      .replace(/_/g, '-')
      .toLowerCase();
  }

  /**
   * PascalCase 转换
   */
  toPascalCase(str) {
    return String(str)
      .split(/[-_]/)
      .map(word => word.charAt(0).toUpperCase() + word.slice(1))
      .join('');
  }

  /**
   * camelCase 转换
   */
  toCamelCase(str) {
    const pascal = this.toPascalCase(str);
    return pascal.charAt(0).toLowerCase() + pascal.slice(1);
  }

  /**
   * snake_case 转换
   */
  toSnakeCase(str) {
    return str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');
  }
}

module.exports = BaseGenerator;

