#!/usr/bin/env python3
"""
测试套件执行报告生成器

用途:
- 统计测试用例数量
- 分析测试覆盖率
- 生成测试执行摘要
- 输出测试报告
"""

import os
import sys
import json
import subprocess
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Any


class TestReportGenerator:
    """测试报告生成器"""
    
    def __init__(self, test_suite_path: str):
        self.test_suite_path = Path(test_suite_path)
        self.tests_path = self.test_suite_path / "tests"
        self.report_data = {
            "generated_at": datetime.now().isoformat(),
            "test_suites": {},
            "summary": {
                "total_test_files": 0,
                "total_test_cases": 0,
                "test_categories": {}
            }
        }
    
    def count_test_cases(self, file_path: Path) -> int:
        """统计测试文件中的测试用例数量"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
                # 统计以async def test_或def test_开头的函数
                count = content.count('async def test_') + content.count('def test_')
                return count
        except Exception as e:
            print(f"Error reading {file_path}: {e}")
            return 0
    
    def analyze_test_directory(self, dir_path: Path, category: str) -> Dict[str, Any]:
        """分析测试目录"""
        test_files = list(dir_path.glob("test_*.py"))
        
        category_data = {
            "test_files": [],
            "total_files": len(test_files),
            "total_cases": 0
        }
        
        for test_file in test_files:
            case_count = self.count_test_cases(test_file)
            file_info = {
                "file_name": test_file.name,
                "relative_path": str(test_file.relative_to(self.tests_path)),
                "test_cases": case_count
            }
            category_data["test_files"].append(file_info)
            category_data["total_cases"] += case_count
        
        return category_data
    
    def generate_report(self) -> Dict[str, Any]:
        """生成测试报告"""
        print("正在分析测试套件...")
        
        # 分析各个测试目录
        test_categories = {
            "unit": self.tests_path / "unit",
            "integration": self.tests_path / "integration",
            "e2e": self.tests_path / "e2e",
            "uat": self.tests_path / "uat",
            "performance": self.tests_path / "performance",
            "security": self.tests_path / "security"
        }
        
        for category, path in test_categories.items():
            if path.exists():
                print(f"分析 {category} 测试...")
                category_data = self.analyze_test_directory(path, category)
                self.report_data["test_suites"][category] = category_data
                
                # 更新汇总信息
                self.report_data["summary"]["total_test_files"] += category_data["total_files"]
                self.report_data["summary"]["total_test_cases"] += category_data["total_cases"]
                self.report_data["summary"]["test_categories"][category] = {
                    "files": category_data["total_files"],
                    "cases": category_data["total_cases"]
                }
        
        return self.report_data
    
    def print_report(self):
        """打印测试报告"""
        print("\n" + "="*60)
        print("  Novalon后台管理系统 - 测试套件执行报告")
        print("="*60)
        print(f"\n生成时间: {self.report_data['generated_at']}")
        print("\n" + "-"*60)
        print("  测试套件统计")
        print("-"*60)
        
        for category, data in self.report_data["test_suites"].items():
            print(f"\n{category.upper()} 测试:")
            print(f"  测试文件数: {data['total_files']}")
            print(f"  测试用例数: {data['total_cases']}")
            
            if data['test_files']:
                print(f"  测试文件列表:")
                for file_info in data['test_files']:
                    print(f"    - {file_info['file_name']}: {file_info['test_cases']} 个用例")
        
        print("\n" + "-"*60)
        print("  汇总信息")
        print("-"*60)
        print(f"\n总测试文件数: {self.report_data['summary']['total_test_files']}")
        print(f"总测试用例数: {self.report_data['summary']['total_test_cases']}")
        
        print("\n测试分类统计:")
        for category, stats in self.report_data["summary"]["test_categories"].items():
            print(f"  {category}: {stats['files']} 文件, {stats['cases']} 用例")
        
        print("\n" + "="*60)
    
    def save_report(self, output_file: str):
        """保存测试报告到文件"""
        output_path = self.test_suite_path / output_file
        
        with open(output_path, 'w', encoding='utf-8') as f:
            json.dump(self.report_data, f, indent=2, ensure_ascii=False)
        
        print(f"\n测试报告已保存到: {output_path}")
    
    def generate_markdown_report(self, output_file: str):
        """生成Markdown格式的测试报告"""
        output_path = self.test_suite_path / output_file
        
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write("# Novalon后台管理系统 - 测试套件执行报告\n\n")
            f.write(f"**生成时间**: {self.report_data['generated_at']}\n\n")
            
            f.write("## 测试套件统计\n\n")
            
            for category, data in self.report_data["test_suites"].items():
                f.write(f"### {category.upper()} 测试\n\n")
                f.write(f"- **测试文件数**: {data['total_files']}\n")
                f.write(f"- **测试用例数**: {data['total_cases']}\n\n")
                
                if data['test_files']:
                    f.write("**测试文件列表**:\n\n")
                    for file_info in data['test_files']:
                        f.write(f"- `{file_info['file_name']}`: {file_info['test_cases']} 个用例\n")
                    f.write("\n")
            
            f.write("## 汇总信息\n\n")
            f.write(f"- **总测试文件数**: {self.report_data['summary']['total_test_files']}\n")
            f.write(f"- **总测试用例数**: {self.report_data['summary']['total_test_cases']}\n\n")
            
            f.write("### 测试分类统计\n\n")
            f.write("| 测试类型 | 文件数 | 用例数 |\n")
            f.write("|---------|--------|--------|\n")
            for category, stats in self.report_data["summary"]["test_categories"].items():
                f.write(f"| {category} | {stats['files']} | {stats['cases']} |\n")
            
            f.write("\n## 测试执行建议\n\n")
            f.write("### 快速测试\n")
            f.write("```bash\n")
            f.write("./run_tests.sh integration -v\n")
            f.write("```\n\n")
            
            f.write("### 完整测试\n")
            f.write("```bash\n")
            f.write("./run_tests.sh all -v\n")
            f.write("```\n\n")
            
            f.write("### UAT验收测试\n")
            f.write("```bash\n")
            f.write("./run_uat_tests.sh all -v\n")
            f.write("```\n\n")
            
            f.write("## 测试报告查看\n\n")
            f.write("### 查看覆盖率报告\n")
            f.write("```bash\n")
            f.write("open htmlcov/all/index.html\n")
            f.write("```\n\n")
            
            f.write("### 查看Allure报告\n")
            f.write("```bash\n")
            f.write("allure serve allure-results/all\n")
            f.write("```\n")
        
        print(f"Markdown报告已保存到: {output_path}")


def main():
    """主函数"""
    # 获取测试套件路径
    script_path = Path(__file__).parent
    test_suite_path = script_path
    
    # 创建报告生成器
    generator = TestReportGenerator(str(test_suite_path))
    
    # 生成报告
    generator.generate_report()
    
    # 打印报告
    generator.print_report()
    
    # 保存JSON报告
    generator.save_report("test_suite_report.json")
    
    # 生成Markdown报告
    generator.generate_markdown_report("TEST_SUITE_REPORT.md")
    
    print("\n✅ 测试套件报告生成完成!")


if __name__ == "__main__":
    main()
