#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
E2E/UAT 测试启动脚本

用于启动整个后台系统的端到端测试和用户验收测试
支持在开发环境直接运行，无需 Docker 部署
"""

import os
import sys
import subprocess
import argparse
from pathlib import Path


def parse_args():
    """解析命令行参数"""
    parser = argparse.ArgumentParser(description='E2E/UAT 测试启动脚本')
    
    parser.add_argument(
        '--env',
        type=str,
        default='dev',
        choices=['dev', 'test', 'prod'],
        help='运行环境 (默认: dev)'
    )
    
    parser.add_argument(
        '--database',
        type=str,
        default='h2',
        choices=['h2', 'postgresql'],
        help='测试数据库类型 (默认: h2)'
    )
    
    parser.add_argument(
        '--backend-url',
        type=str,
        default='http://localhost:8084',
        help='后端服务地址 (默认: http://localhost:8084)'
    )
    
    parser.add_argument(
        '--frontend-url',
        type=str,
        default='http://localhost:3000',
        help='前端服务地址 (默认: http://localhost:3000)'
    )
    
    parser.add_argument(
        '--test-dir',
        type=str,
        default='test-suite/api',
        help='测试目录路径 (默认: test-suite/api)'
    )
    
    parser.add_argument(
        '--test-case',
        type=str,
        default=None,
        help='指定要运行的测试用例文件或类 (默认: 运行所有测试)'
    )
    
    parser.add_argument(
        '--parallel',
        action='store_true',
        help='启用并行测试'
    )
    
    parser.add_argument(
        '--reruns',
        type=int,
        default=0,
        help='失败用例重跑次数 (默认: 0)'
    )
    
    parser.add_argument(
        '--html-report',
        type=str,
        default='test-suite/report.html',
        help='HTML 测试报告路径 (默认: test-suite/report.html)'
    )
    
    parser.add_argument(
        '--junit-report',
        type=str,
        default='test-suite/junit.xml',
        help='JUnit 测试报告路径 (默认: test-suite/junit.xml)'
    )
    
    parser.add_argument(
        '--verbose',
        action='store_true',
        help='启用详细输出模式'
    )
    
    parser.add_argument(
        '--coverage',
        action='store_true',
        help='启用代码覆盖率报告'
    )
    
    parser.add_argument(
        '--dry-run',
        action='store_true',
        help='仅打印命令，不实际执行'
    )
    
    return parser.parse_args()


def check_dependencies():
    """检查依赖是否安装"""
    required_packages = [
        'pytest',
        'pytest-html',
        'pytest-rerunfailures',
        'pytest-asyncio',
        'requests',
        'pytest-dependency'
    ]
    
    missing_packages = []
    for package in required_packages:
        try:
            __import__(package.replace('-', '_'))
        except ImportError:
            missing_packages.append(package)
    
    if missing_packages:
        print("❌ 缺少必要的 Python 包，请运行:")
        print(f"   pip install {' '.join(missing_packages)}")
        sys.exit(1)


def setup_environment(args):
    """设置环境变量"""
    env_vars = {
        'ENV': args.env,
        'DATABASE': args.database,
        'BASE_URL': args.backend_url,
        'FRONTEND_URL': args.frontend_url,
        'TEST_MODE': 'true'
    }
    
    for key, value in env_vars.items():
        os.environ[key] = value
    
    print(f"✅ 环境变量已设置:")
    for key, value in env_vars.items():
        print(f"   {key}={value}")


def run_pytest(args):
    """运行 pytest 测试"""
    cmd = [
        sys.executable,
        '-m',
        'pytest',
        args.test_dir,
        f'--html={args.html_report}',
        f'--junitxml={args.junit_report}',
        '--self-contained-html'
    ]
    
    if args.verbose:
        cmd.append('-v')
    
    if args.parallel:
        cmd.extend(['-n', 'auto'])
    
    if args.reruns > 0:
        cmd.extend(['--reruns', str(args.reruns)])
    
    if args.test_case:
        cmd.append(args.test_case)
    
    if args.coverage:
        cmd.extend([
            '--cov=test_suite',
            '--cov-report=html:test-suite/coverage',
            '--cov-report=term'
        ])
    
    print(f"\n🚀 运行测试命令:")
    print(f"   {' '.join(cmd)}\n")
    
    if args.dry_run:
        print("✅ 干运行模式，测试未执行")
        return 0
    
    result = subprocess.run(cmd)
    return result.returncode


def main():
    """主函数"""
    args = parse_args()
    
    print("=" * 60)
    print("🔧 E2E/UAT 测试启动脚本")
    print("=" * 60)
    
    # 检查依赖
    print("\n📦 检查依赖...")
    check_dependencies()
    print("✅ 依赖检查通过")
    
    # 设置环境
    print("\n⚙️  设置环境...")
    setup_environment(args)
    
    # 运行测试
    print("\n🧪 运行测试...")
    exit_code = run_pytest(args)
    
    # 输出结果
    print("\n" + "=" * 60)
    if exit_code == 0:
        print("✅ 测试全部通过!")
    else:
        print(f"❌ 测试失败 (退出码: {exit_code})")
    print("=" * 60)
    
    # 输出报告路径
    print(f"\n📊 测试报告:")
    print(f"   HTML: file://{os.path.abspath(args.html_report)}")
    print(f"   JUnit: {os.path.abspath(args.junit_report)}")
    
    if args.coverage:
        print(f"   Coverage: file://{os.path.abspath('test-suite/coverage/index.html')}")
    
    sys.exit(exit_code)


if __name__ == '__main__':
    main()
