#!/usr/bin/env node

/**
 * 测试生成器CLI工具
 * 用于从命令行生成测试代码
 */

const fs = require('fs');
const path = require('path');
const TestCodeGenerator = require('./test-code-generator');
const NaturalLanguageParser = require('./natural-language-parser');

class TestGeneratorCLI {
  constructor() {
    this.generator = new TestCodeGenerator();
    this.nlParser = new NaturalLanguageParser();
  }

  /**
   * 显示帮助信息
   */
  showHelp() {
    console.log(`
DC-TOM 测试代码生成器

用法:
  node cli.js <command> [options]

命令:
  generate <input.json> [output.cy.js]   从JSON文件生成测试代码
  parse <input.txt> [output.cy.js]       从自然语言描述生成测试代码
  validate <input.json>                  验证JSON文件格式
  example                               生成示例JSON文件
  nl-example                           生成自然语言描述示例
  help                                  显示帮助信息

选项:
  -o, --output <file>                   指定输出文件路径
  -d, --directory <dir>                 指定输出目录
  -f, --force                          强制覆盖已存在的文件

示例:
  node cli.js generate test-description.json
  node cli.js parse natural-description.txt
  node cli.js generate test-description.json -o my-test.cy.js
  node cli.js parse natural-description.txt -o my-test.cy.js
  node cli.js validate test-description.json
  node cli.js example
  node cli.js nl-example
    `);
  }

  /**
   * 生成自然语言描述示例
   */
  generateNaturalLanguageExample() {
    const exampleText = `目标页面：首页
测试内容：
1，在告警总览内查询今日布袋告警数据。
2，查询布袋总数
3，在首页查看顶部区域综合健康度的布袋健康度

---

目标页面：设备管理
测试内容：
1，搜索设备名称为“除尘器001”的设备
2，验证搜索结果表格显示正常
3，点击重置按钮清空搜索条件

---

目标页面：布袋周期
测试内容：
1，在仓室输入框中输入“A仓室”
2，在除尘器名称输入框中输入“1#除尘器”
3，点击查询按钮执行搜索
4，验证表格显示搜索结果
5，点击更换周期分析按钮打开对话框`;

    const outputPath = path.join(process.cwd(), 'natural-language-test-example.txt');
    fs.writeFileSync(outputPath, exampleText, 'utf8');
    console.log(`✅ 自然语言描述示例已生成: ${outputPath}`);
  }
  generateExample() {
    const exampleJSON = {
      "testSuite": {
        "name": "布袋周期管理功能测试",
        "module": "布袋周期",
        "description": "测试布袋周期页面的基本功能",
        "beforeEach": {
          "login": true,
          "visit": "collectorList",
          "waitFor": [
            "[data-testid=\"collector-list-container\"]"
          ]
        },
        "scenarios": [
          {
            "name": "应该显示页面的所有核心组件",
            "type": "ui",
            "description": "验证页面基本元素的可见性",
            "priority": "high",
            "steps": [
              {
                "action": "verify",
                "target": "{container}",
                "value": {
                  "assertion": "be.visible"
                },
                "description": "检查主容器"
              },
              {
                "action": "verify", 
                "target": "{searchForm}",
                "value": {
                  "assertion": "be.visible"
                },
                "description": "检查搜索表单"
              },
              {
                "action": "verify",
                "target": "{table}",
                "value": {
                  "assertion": "be.visible"
                },
                "description": "检查数据表格"
              }
            ]
          },
          {
            "name": "应该能够进行搜索操作",
            "type": "interaction",
            "description": "测试搜索功能的基本操作",
            "priority": "high",
            "steps": [
              {
                "action": "type",
                "target": "[data-testid=\"collector-compart-input\"]",
                "value": "测试仓室",
                "options": {
                  "clear": true
                },
                "description": "输入仓室名称"
              },
              {
                "action": "type",
                "target": "[data-testid=\"collector-duster-name-input\"]",
                "value": "测试除尘器",
                "options": {
                  "clear": true
                },
                "description": "输入除尘器名称"
              },
              {
                "action": "click",
                "target": "{searchButton}",
                "description": "点击搜索按钮"
              },
              {
                "action": "wait",
                "value": 1000,
                "description": "等待搜索结果加载"
              }
            ],
            "expectedResults": [
              {
                "target": "{table}",
                "assertion": "be.visible"
              }
            ]
          },
          {
            "name": "应该能够重置搜索条件",
            "type": "interaction",
            "description": "测试重置搜索功能",
            "priority": "medium",
            "steps": [
              {
                "action": "type",
                "target": "[data-testid=\"collector-compart-input\"]",
                "value": "测试数据",
                "description": "输入测试数据"
              },
              {
                "action": "click",
                "target": "{resetButton}",
                "description": "点击重置按钮"
              }
            ],
            "expectedResults": [
              {
                "target": "[data-testid=\"collector-compart-input\"]",
                "assertion": "have.value",
                "value": ""
              }
            ]
          },
          {
            "name": "应该处理网络错误",
            "type": "error",
            "description": "测试网络错误的处理",
            "priority": "medium",
            "steps": [
              {
                "action": "intercept",
                "value": {
                  "method": "GET",
                  "url": "**/bag/cycle/getReplaceListPage",
                  "statusCode": 500,
                  "error": "服务器错误",
                  "alias": "apiError"
                },
                "description": "模拟API错误"
              },
              {
                "action": "click",
                "target": "{searchButton}",
                "description": "触发搜索"
              }
            ],
            "expectedResults": [
              {
                "target": "{container}",
                "assertion": "be.visible"
              }
            ]
          }
        ]
      }
    };

    const outputPath = path.join(process.cwd(), 'test-description-example.json');
    fs.writeFileSync(outputPath, JSON.stringify(exampleJSON, null, 2), 'utf8');
    console.log(`✅ 示例JSON文件已生成: ${outputPath}`);
  }

  /**
   * 验证JSON文件
   */
  validateJSON(inputPath) {
    try {
      if (!fs.existsSync(inputPath)) {
        throw new Error(`文件不存在: ${inputPath}`);
      }

      const jsonContent = fs.readFileSync(inputPath, 'utf8');
      const testDescription = JSON.parse(jsonContent);

      // 使用生成器进行验证
      this.generator.validateTestDescription(testDescription);
      
      console.log('✅ JSON文件格式验证通过');
      return true;
    } catch (error) {
      console.error('❌ JSON文件验证失败:', error.message);
      return false;
    }
  }

  /**
   * 从自然语言描述生成测试代码
   */
  parseNaturalLanguage(inputPath, outputPath = null) {
    try {
      if (!fs.existsSync(inputPath)) {
        throw new Error(`文件不存在: ${inputPath}`);
      }

      // 读取自然语言描述
      const naturalDescription = fs.readFileSync(inputPath, 'utf8');
      console.log('ℹ️ 读取自然语言描述:', inputPath);

      // 解析为结构化数据
      const testStructure = this.nlParser.parseDescription(naturalDescription);
      console.log('✅ 自然语言解析成功');

      // 生成测试代码
      const testCode = this.generator.generateFromJSON(testStructure);

      // 确定输出路径
      if (!outputPath) {
        const baseName = path.basename(inputPath, '.txt');
        outputPath = path.join(process.cwd(), 'cypress', 'e2e', 'generated', `${baseName}.cy.js`);
      }

      // 确保输出目录存在
      const outputDir = path.dirname(outputPath);
      if (!fs.existsSync(outputDir)) {
        fs.mkdirSync(outputDir, { recursive: true });
      }

      // 写入文件
      fs.writeFileSync(outputPath, testCode, 'utf8');
      
      console.log('✅ 测试代码生成成功!');
      console.log(`📄 输入文件: ${inputPath}`);
      console.log(`📝 输出文件: ${outputPath}`);
      
      // 显示解析结果摘要
      console.log('\n🔍 解析结果摘要:');
      console.log(`   测试套件: ${testStructure.testSuite.name}`);
      console.log(`   目标模块: ${testStructure.testSuite.module}`);
      console.log(`   测试场景数: ${testStructure.testSuite.scenarios.length}`);
      
      return true;
    } catch (error) {
      console.error('❌ 自然语言解析失败:', error.message);
      return false;
    }
  }
  generateTest(inputPath, outputPath = null) {
    try {
      // 验证输入文件
      if (!this.validateJSON(inputPath)) {
        return false;
      }

      // 读取JSON文件
      const jsonContent = fs.readFileSync(inputPath, 'utf8');
      const testDescription = JSON.parse(jsonContent);

      // 确定输出路径
      if (!outputPath) {
        const baseName = path.basename(inputPath, '.json');
        outputPath = path.join(process.cwd(), 'cypress', 'e2e', 'generated', `${baseName}.cy.js`);
      }

      // 生成测试文件
      const generatedPath = this.generator.generateTestFile(testDescription, outputPath);
      
      console.log('✅ 测试代码生成成功!');
      console.log(`📄 输入文件: ${inputPath}`);
      console.log(`📝 输出文件: ${generatedPath}`);
      
      return true;
    } catch (error) {
      console.error('❌ 测试代码生成失败:', error.message);
      return false;
    }
  }

  /**
   * 解析命令行参数
   */
  parseArgs(args) {
    const options = {
      command: null,
      input: null,
      output: null,
      directory: null,
      force: false
    };

    for (let i = 0; i < args.length; i++) {
      const arg = args[i];
      
      switch (arg) {
        case 'generate':
        case 'parse':
        case 'validate':
        case 'example':
        case 'nl-example':
        case 'help':
          options.command = arg;
          if (args[i + 1] && !args[i + 1].startsWith('-')) {
            options.input = args[i + 1];
            i++;
          }
          break;
        case '-o':
        case '--output':
          options.output = args[i + 1];
          i++;
          break;
        case '-d':
        case '--directory':
          options.directory = args[i + 1];
          i++;
          break;
        case '-f':
        case '--force':
          options.force = true;
          break;
      }
    }

    return options;
  }

  /**
   * 运行CLI
   */
  run() {
    const args = process.argv.slice(2);
    
    if (args.length === 0) {
      this.showHelp();
      return;
    }

    const options = this.parseArgs(args);

    switch (options.command) {
      case 'generate':
        if (!options.input) {
          console.error('❌ 请指定JSON输入文件');
          return;
        }
        this.generateTest(options.input, options.output);
        break;
      case 'parse':
        if (!options.input) {
          console.error('❌ 请指定自然语言描述文件');
          return;
        }
        this.parseNaturalLanguage(options.input, options.output);
        break;
      case 'validate':
        if (!options.input) {
          console.error('❌ 请指定要验证的JSON文件');
          return;
        }
        this.validateJSON(options.input);
        break;
      case 'example':
        this.generateExample();
        break;
      case 'nl-example':
        this.generateNaturalLanguageExample();
        break;
      case 'help':
      default:
        this.showHelp();
        break;
    }
  }
}

// 如果直接运行此文件，执行CLI
if (require.main === module) {
  const cli = new TestGeneratorCLI();
  cli.run();
}

module.exports = TestGeneratorCLI;