/**
 * Regression Scheduler - 智能回归测试调度器
 * 
 * 职责：
 * 1. 根据修复范围选择回归策略
 * 2. 智能选择需要回归的测试用例
 * 3. 优化并行度和执行顺序
 * 4. 生成回归测试计划
 * 
 * @module testing/tools/regression-scheduler
 * @version 1.0.0
 */

import type {
  AIAnalysisResult,
  RegressionStrategy,
  RegressionPlan,
  TestCase,
} from './types';

/**
 * 回归调度器
 */
export class RegressionScheduler {
  /**
   * 生成回归测试计划
   * @param analysis - AI分析结果
   * @param allTestCases - 所有测试用例
   * @returns 回归测试计划
   */
  async createRegressionPlan(
    analysis: AIAnalysisResult,
    allTestCases: TestCase[]
  ): Promise<RegressionPlan> {
    console.log('[RegressionScheduler] 生成回归测试计划...');
    console.log(`[RegressionScheduler] 策略: ${analysis.regressionStrategy}`);

    const strategy = analysis.regressionStrategy;
    const testIds = await this.selectTestCases(strategy, analysis, allTestCases);
    const estimatedDuration = this.estimateDuration(testIds, allTestCases);
    const parallel = this.calculateParallelism(strategy, testIds.length);

    const plan: RegressionPlan = {
      strategy,
      testIds,
      estimatedDuration,
      parallel,
      reason: this.getReason(strategy, analysis),
    };

    console.log(`[RegressionScheduler] 选择了 ${testIds.length} 个测试用例`);
    console.log(`[RegressionScheduler] 预计耗时: ${this.formatDuration(estimatedDuration)}`);
    console.log(`[RegressionScheduler] 并行度: ${parallel}`);

    return plan;
  }

  /**
   * 选择测试用例
   */
  private async selectTestCases(
    strategy: RegressionStrategy,
    analysis: AIAnalysisResult,
    allTestCases: TestCase[]
  ): Promise<string[]> {
    switch (strategy) {
      case 'minimal':
        return this.selectMinimal(analysis);
      case 'module':
        return this.selectModule(analysis, allTestCases);
      case 'dependency':
        return this.selectDependency(analysis, allTestCases);
      case 'full':
        return this.selectFull(allTestCases);
      default:
        return [];
    }
  }

  /**
   * 策略1：最小范围
   */
  private selectMinimal(analysis: AIAnalysisResult): string[] {
    // 只回归失败的测试用例本身
    return [analysis.testResult.testId];
  }

  /**
   * 策略2：模块范围
   */
  private selectModule(analysis: AIAnalysisResult, allTestCases: TestCase[]): string[] {
    // 回归同模块的所有测试
    // 简化实现：返回所有测试
    return allTestCases.map((tc) => tc.testId);
  }

  /**
   * 策略3：依赖范围
   */
  private selectDependency(
    analysis: AIAnalysisResult,
    allTestCases: TestCase[]
  ): string[] {
    // 回归依赖链上的所有测试
    // 简化实现：返回所有P0测试
    return allTestCases.filter((tc) => tc.priority === 'P0').map((tc) => tc.testId);
  }

  /**
   * 策略4：全量回归
   */
  private selectFull(allTestCases: TestCase[]): string[] {
    // 回归所有测试
    return allTestCases.map((tc) => tc.testId);
  }

  /**
   * 估算执行时间
   */
  private estimateDuration(testIds: string[], allTestCases: TestCase[]): number {
    const avgDuration = 30000; // 默认30秒/用例
    return testIds.length * avgDuration;
  }

  /**
   * 计算并行度
   */
  private calculateParallelism(strategy: RegressionStrategy, testCount: number): number {
    if (strategy === 'minimal') return 1;
    if (strategy === 'module') return Math.min(2, testCount);
    if (strategy === 'dependency') return Math.min(3, testCount);
    return Math.min(4, testCount);
  }

  /**
   * 获取策略原因
   */
  private getReason(strategy: RegressionStrategy, analysis: AIAnalysisResult): string {
    const reasons: Record<RegressionStrategy, string> = {
      minimal: `Level ${analysis.fixLevel.replace('level', '')}修复，影响范围小`,
      module: '修复影响模块内多个功能',
      dependency: '修复涉及依赖链',
      full: '高风险修复，需全量验证',
    };
    return reasons[strategy];
  }

  /**
   * 格式化时长
   */
  private formatDuration(ms: number): string {
    if (ms < 60000) return `${Math.round(ms / 1000)}秒`;
    return `${Math.round(ms / 60000)}分钟`;
  }
}

/**
 * 便捷函数：创建回归计划
 */
export async function createRegressionPlan(
  analysis: AIAnalysisResult,
  allTestCases: TestCase[]
): Promise<RegressionPlan> {
  const scheduler = new RegressionScheduler();
  return await scheduler.createRegressionPlan(analysis, allTestCases);
}
