#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
独立测试执行脚本
在独立进程中运行 Playwright 测试，避免 asyncio 环境冲突

用法：
    python run_case_worker.py <execution_id> <case_id>
"""

import asyncio
import json
import os
import sys
from datetime import datetime

# 添加项目路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from playwright.sync_api import sync_playwright
from app.database import async_session_maker
from app.models.execution import Execution
from app.models.case_result import CaseResult
from app.models.test_case import TestCase
from app.executors.playwright_executor import PlaywrightExecutor
from sqlalchemy import select


async def run_case(execution_id: str, case_id: str):
    """执行单个测试用例"""
    async with async_session_maker() as db:
        # 获取用例结果
        result_query = select(CaseResult).where(
            CaseResult.case_id == case_id,
            CaseResult.execution_id == execution_id
        )
        res = await db.execute(result_query)
        case_result = res.scalar_one_or_none()

        if not case_result:
            print(f"Error: Case result not found for {case_id}/{execution_id}")
            return

        # 获取用例定义
        case_query = select(TestCase).where(TestCase.id == case_id)
        case_res = await db.execute(case_query)
        case = case_res.scalar_one_or_none()

        if not case:
            case_result.status = "skipped"
            case_result.error_message = "用例定义不存在"
            await db.flush()
            await db.commit()
            return

        # 更新状态为运行中
        case_result.status = "running"
        case_result.start_time = datetime.now()
        await db.flush()
        await db.commit()

        # 创建执行器并执行
        executor = PlaywrightExecutor({'headless': True, 'timeout': 30000, 'screenshot': True})

        try:
            result = executor.execute_case(case=case.to_dict())

            # 更新结果
            case_result.status = result.status
            case_result.duration = result.duration
            case_result.end_time = datetime.now()
            case_result.retry_count = result.retry_count
            case_result.error_message = result.error_message
            case_result.steps_result = [
                {
                    "order": s.order,
                    "name": s.name,
                    "action": s.action,
                    "status": s.status,
                    "duration": s.duration,
                    "screenshot": s.screenshot,
                    "log": s.log,
                    "error": s.error,
                }
                for s in result.steps_result
            ]
            await db.flush()
            await db.commit()
            print(f"DONE: {case.name} - {result.status} ({result.duration:.2f}s)")

        except Exception as e:
            case_result.status = "failed"
            case_result.error_message = f"执行异常: {str(e)}"
            case_result.end_time = datetime.now()
            await db.flush()
            await db.commit()
            print(f"ERROR: {case.name}: {e}")

        finally:
            executor.stop()
            await db.close()


if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python run_case_worker.py <execution_id> <case_id>")
        sys.exit(1)

    execution_id = sys.argv[1]
    case_id = sys.argv[2]
    print(f"Running case {case_id} for execution {execution_id}")
    asyncio.run(run_case(execution_id, case_id))
