#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
脚本集成测试
测试从创建项目、编辑脚本到VWED任务调度的完整流程
"""

import asyncio
import json
import sys
import os
from pathlib import Path

# 添加项目根目录到 Python 路径
sys.path.insert(0, str(Path(__file__).parent.parent))

from services.online_script.script_file_service import get_file_service
from services.online_script.script_engine_service import get_script_engine
from services.online_script.script_task_integration import get_task_integration
from services.online_script.script_registry_service import get_global_registry
from utils.logger import get_logger

logger = get_logger("test.script_integration")


class ScriptIntegrationTest:
    """脚本集成测试类"""
    
    def __init__(self):
        self.file_service = get_file_service()
        self.script_engine = get_script_engine()
        self.task_integration = get_task_integration()
        self.registry = get_global_registry()
        
        # 测试数据
        self.test_project_id = None
        self.test_file_id = None
        self.test_script_id = None
        
    async def run_full_test(self):
        """运行完整的集成测试"""
        try:
            logger.info("=== 开始脚本集成测试 ===")
            
            # 第1步：创建测试项目
            await self.test_create_project()
            
            # 第2步：创建测试脚本文件
            await self.test_create_script_file()
            
            # 第3步：编辑脚本内容
            await self.test_update_script_content()
            
            # 第4步：启动脚本服务
            await self.test_start_script_service()
            
            # 第5步：测试脚本函数调用
            await self.test_execute_script_function()
            
            # 第6步：测试VWED任务集成
            await self.test_vwed_task_integration()
            
            # 第7步：测试API接口调用
            await self.test_dynamic_api_routes()
            
            # 第8步：获取注册中心状态
            await self.test_registry_status()
            
            # 第9步：停止脚本服务
            await self.test_stop_script_service()
            
            logger.info("=== 脚本集成测试完成 ===")
            
        except Exception as e:
            logger.error(f"集成测试失败: {e}", exc_info=True)
            raise
    
    async def test_create_project(self):
        """测试创建项目"""
        logger.info("测试1: 创建脚本项目")
        
        result = await self.file_service.create_project(
            project_name="测试项目_集成测试",
            description="用于集成测试的项目",
            created_by="test_user"
        )
        
        assert result["success"], f"创建项目失败: {result.get('error')}"
        self.test_project_id = result["project"]["id"]
        
        logger.info(f"✓ 项目创建成功，ID: {self.test_project_id}")
    
    async def test_create_script_file(self):
        """测试创建脚本文件"""
        logger.info("测试2: 创建脚本文件")
        
        # 初始的简单脚本内容
        initial_content = '''def boot():
    """脚本启动函数"""
    VWED.log.sync_info("测试脚本启动中...")
    
    # 这里会在后续步骤中添加更多功能
    VWED.log.sync_info("测试脚本启动完成")
'''
        
        result = await self.file_service.create_file(
            project_id=self.test_project_id,
            file_name="test_integration.py",
            file_path="test_integration.py",
            content=initial_content,
            file_type="python",
            created_by="test_user"
        )
        
        assert result["success"], f"创建文件失败: {result.get('error')}"
        self.test_file_id = result["file"]["id"]
        
        logger.info(f"✓ 脚本文件创建成功，ID: {self.test_file_id}")
    
    async def test_update_script_content(self):
        """测试更新脚本内容"""
        logger.info("测试3: 编辑脚本内容")
        
        # 完整的测试脚本内容
        updated_content = '''def boot():
    """脚本启动函数 - 注册各种服务"""
    VWED.log.sync_info("集成测试脚本启动中...")
    
    # 注册API接口
    setup_api_routes()
    
    # 注册自定义函数
    setup_functions()
    
    # 注册事件监听器
    setup_events()
    
    # 注册定时任务
    setup_timers()
    
    VWED.log.sync_info("集成测试脚本服务注册完成")

def setup_api_routes():
    """设置API接口"""
    
    @VWED.api.get("/test/hello", description="测试问候接口")
    def hello_api(request_data):
        name = request_data["query_params"].get("name", "World")
        VWED.log.sync_info(f"API调用: hello_api, name={name}")
        return {
            "message": f"Hello, {name}!",
            "timestamp": VWED.util.now(),
            "script_id": VWED.get_script_id()
        }
    
    @VWED.api.post("/test/calculate", description="测试计算接口")
    def calculate_api(request_data):
        data = request_data["body"]
        a = data.get("a", 0)
        b = data.get("b", 0)
        operation = data.get("operation", "add")
        
        if operation == "add":
            result = a + b
        elif operation == "subtract":
            result = a - b
        elif operation == "multiply":
            result = a * b
        elif operation == "divide":
            result = a / b if b != 0 else "Error: Division by zero"
        else:
            result = "Error: Unknown operation"
        
        VWED.log.sync_info(f"API计算: {a} {operation} {b} = {result}")
        return {
            "operation": operation,
            "operand_a": a,
            "operand_b": b,
            "result": result,
            "timestamp": VWED.util.now()
        }

def setup_functions():
    """设置自定义函数"""
    
    @VWED.function.register("test_add", description="测试加法函数")
    def test_add(args):
        """供VWED任务调用的加法函数"""
        a = args.get("a", 0)
        b = args.get("b", 0)
        result = a + b
        
        VWED.log.sync_info(f"函数调用: test_add({a}, {b}) = {result}")
        return {
            "result": result,
            "operation": "addition",
            "inputs": {"a": a, "b": b}
        }
    
    @VWED.function.register("test_process_data", description="测试数据处理函数")
    def test_process_data(args):
        """数据处理测试函数"""
        data_list = args.get("data", [])
        process_type = args.get("type", "count")
        
        if process_type == "count":
            result = len(data_list)
        elif process_type == "sum":
            result = sum(data_list) if all(isinstance(x, (int, float)) for x in data_list) else "Error: Non-numeric data"
        elif process_type == "filter_positive":
            result = [x for x in data_list if isinstance(x, (int, float)) and x > 0]
        else:
            result = data_list
        
        VWED.log.sync_info(f"数据处理: type={process_type}, input_size={len(data_list)}, result={result}")
        return {
            "processed_data": result,
            "process_type": process_type,
            "input_size": len(data_list)
        }
    
    @VWED.function.register("test_async_task", description="测试异步任务函数")
    async def test_async_task(args):
        """异步任务测试函数"""
        task_name = args.get("task_name", "default_task")
        delay = args.get("delay", 1)
        
        await VWED.log.info(f"异步任务开始: {task_name}, 延迟: {delay}秒")
        await VWED.util.async_sleep(delay)
        await VWED.log.info(f"异步任务完成: {task_name}")
        
        return {
            "task_name": task_name,
            "delay_seconds": delay,
            "completed": True,
            "completion_time": VWED.util.now()
        }

def setup_events():
    """设置事件监听器"""
    
    @VWED.event.listen("test_event")
    def on_test_event(event_data):
        VWED.log.sync_info(f"接收到测试事件: {event_data}")
        
        # 存储事件计数
        event_count = VWED.data.get("event_count", 0)
        VWED.data.set("event_count", event_count + 1)
    
    @VWED.event.listen("task_completed", priority=1)
    def on_task_completed(event_data):
        task_id = event_data.get("task_id", "unknown")
        VWED.log.sync_info(f"任务完成通知: {task_id}")
        
        # 记录完成的任务
        completed_tasks = VWED.data.get("completed_tasks", [])
        completed_tasks.append({
            "task_id": task_id,
            "completed_at": VWED.util.now()
        })
        VWED.data.set("completed_tasks", completed_tasks)

def setup_timers():
    """设置定时任务"""
    
    @VWED.timer.interval(30)  # 每30秒执行一次
    def heartbeat_timer():
        heartbeat_count = VWED.data.get("heartbeat_count", 0)
        VWED.data.set("heartbeat_count", heartbeat_count + 1)
        VWED.log.sync_info(f"心跳检测 #{heartbeat_count + 1}")
    
    @VWED.timer.once(delay=5)  # 5秒后执行一次
    def initialization_timer():
        VWED.log.sync_info("初始化任务执行")
        VWED.data.set("initialized", True)
        VWED.data.set("init_time", VWED.util.now())

# 辅助函数
def get_test_statistics():
    """获取测试统计信息"""
    return {
        "event_count": VWED.data.get("event_count", 0),
        "heartbeat_count": VWED.data.get("heartbeat_count", 0),
        "completed_tasks": len(VWED.data.get("completed_tasks", [])),
        "initialized": VWED.data.get("initialized", False),
        "init_time": VWED.data.get("init_time", None)
    }
'''
        
        result = await self.file_service.update_file_content(
            file_id=self.test_file_id,
            content=updated_content,
            updated_by="test_user"
        )
        
        assert result["success"], f"更新文件内容失败: {result.get('error')}"
        
        logger.info("✓ 脚本内容更新成功，已添加完整的测试功能")
    
    async def test_start_script_service(self):
        """测试启动脚本服务"""
        logger.info("测试4: 启动脚本服务")
        
        # 构建脚本路径
        script_path = f"projects/测试项目_集成测试/test_integration.py"
        
        result = await self.script_engine.start_script_service(
            script_path=script_path,
            start_params={"test_mode": True}
        )
        
        assert result["success"], f"启动脚本服务失败: {result.get('error')}"
        self.test_script_id = result["script_id"]
        
        logger.info(f"✓ 脚本服务启动成功，Script ID: {self.test_script_id}")
        logger.info(f"  - 注册的接口数: {result['registrations']['apis']}")
        logger.info(f"  - 注册的函数数: {result['registrations']['functions']}")
        logger.info(f"  - 注册的事件数: {result['registrations']['events']}")
        logger.info(f"  - 注册的定时器数: {result['registrations']['timers']}")
    
    async def test_execute_script_function(self):
        """测试执行脚本函数"""
        logger.info("测试5: 执行脚本函数")
        
        # 测试同步函数
        result1 = await self.script_engine.execute_script_function(
            script_id=self.test_script_id,
            function_name="test_add",
            function_args={"a": 15, "b": 25}
        )
        
        assert result1["success"], f"执行test_add函数失败: {result1.get('error')}"
        assert result1["result"]["result"] == 40, "加法函数计算结果错误"
        logger.info(f"✓ 同步函数test_add执行成功: 15 + 25 = {result1['result']['result']}")
        
        # 测试数据处理函数
        result2 = await self.script_engine.execute_script_function(
            script_id=self.test_script_id,
            function_name="test_process_data",
            function_args={"data": [1, 2, 3, -1, 4, -2, 5], "type": "filter_positive"}
        )
        
        assert result2["success"], f"执行test_process_data函数失败: {result2.get('error')}"
        expected_result = [1, 2, 3, 4, 5]
        assert result2["result"]["processed_data"] == expected_result, "数据过滤结果错误"
        logger.info(f"✓ 数据处理函数执行成功: 过滤出正数 {expected_result}")
        
        # 测试异步函数
        result3 = await self.script_engine.execute_script_function(
            script_id=self.test_script_id,
            function_name="test_async_task",
            function_args={"task_name": "integration_test", "delay": 0.5}
        )
        
        assert result3["success"], f"执行test_async_task函数失败: {result3.get('error')}"
        assert result3["result"]["completed"] == True, "异步任务未正确完成"
        logger.info(f"✓ 异步函数test_async_task执行成功")
    
    async def test_vwed_task_integration(self):
        """测试VWED任务系统集成"""
        logger.info("测试6: VWED任务系统集成")
        
        # 获取可用的脚本函数列表
        available_functions = await self.task_integration.get_available_functions()
        
        assert len(available_functions) > 0, "没有可用的脚本函数"
        
        function_names = [func["function_name"] for func in available_functions]
        assert "test_add" in function_names, "test_add函数未在可用函数列表中"
        assert "test_process_data" in function_names, "test_process_data函数未在可用函数列表中"
        
        logger.info(f"✓ 可用脚本函数: {function_names}")
        
        # 模拟从VWED任务中调用脚本函数
        task_context = {
            "task_id": "test_task_001",
            "instance_id": "test_instance_001",
            "block_id": "script_block_001"
        }
        
        result = await self.task_integration.execute_script_function_from_task(
            function_name="test_add",
            function_args={"a": 100, "b": 200},
            task_context=task_context
        )
        
        assert result["success"], f"从任务调用脚本函数失败: {result.get('error')}"
        assert result["result"]["result"] == 300, "任务调用脚本函数计算结果错误"
        
        logger.info(f"✓ VWED任务调用脚本函数成功: 100 + 200 = {result['result']['result']}")
    
    async def test_dynamic_api_routes(self):
        """测试动态API路由（模拟）"""
        logger.info("测试7: 动态API路由测试")
        
        # 获取注册的API路由信息
        registrations = self.registry.get_all_registrations()
        api_routes = registrations.get("api_routes", {})
        
        # 检查是否注册了预期的API路由
        expected_routes = ["GET:/test/hello", "POST:/test/calculate"]
        
        for route_key in expected_routes:
            assert route_key in api_routes, f"API路由 {route_key} 未注册"
            route_info = api_routes[route_key]
            assert route_info["script_id"] == self.test_script_id, f"路由 {route_key} 的script_id不匹配"
        
        logger.info(f"✓ 动态API路由注册成功: {list(api_routes.keys())}")
        
        # 这里可以进一步测试实际的HTTP请求（需要启动FastAPI服务器）
        # 由于是集成测试，我们主要验证注册是否正确
    
    async def test_registry_status(self):
        """测试获取注册中心状态"""
        logger.info("测试8: 获取注册中心状态")
        
        registrations = self.registry.get_all_registrations()
        
        # 验证注册信息
        assert len(registrations["api_routes"]) >= 2, "API路由注册数量不足"
        assert len(registrations["registered_functions"]) >= 3, "函数注册数量不足"
        assert len(registrations["event_listeners"]) >= 1, "事件监听器注册数量不足"
        assert len(registrations["active_scripts"]) >= 1, "活跃脚本数量不足"
        
        logger.info("✓ 注册中心状态检查通过")
        logger.info(f"  - API路由数: {len(registrations['api_routes'])}")
        logger.info(f"  - 注册函数数: {len(registrations['registered_functions'])}")
        logger.info(f"  - 事件监听器数: {len(registrations['event_listeners'])}")
        logger.info(f"  - 活跃脚本数: {len(registrations['active_scripts'])}")
    
    async def test_stop_script_service(self):
        """测试停止脚本服务"""
        logger.info("测试9: 停止脚本服务")
        
        result = await self.script_engine.stop_script_service(self.test_script_id)
        
        assert result["success"], f"停止脚本服务失败: {result.get('error')}"
        
        logger.info("✓ 脚本服务停止成功")
        
        # 验证注册项已被清理
        running_scripts = self.script_engine.get_running_scripts()
        script_ids = [s["script_id"] for s in running_scripts]
        assert self.test_script_id not in script_ids, "脚本服务未正确停止"
        
        logger.info("✓ 脚本注册项清理完成")


async def main():
    """主测试函数"""
    try:
        # 创建测试实例
        test = ScriptIntegrationTest()
        
        # 运行完整的集成测试
        await test.run_full_test()
        
        print("\n" + "="*60)
        print("🎉 脚本集成测试全部通过！")
        print("="*60)
        print("测试覆盖的功能:")
        print("✓ 项目和文件管理")
        print("✓ 脚本内容编辑")
        print("✓ 脚本服务启动和停止")
        print("✓ API接口动态注册")
        print("✓ 自定义函数注册和调用")
        print("✓ 事件系统和定时任务")
        print("✓ VWED任务系统集成")
        print("✓ 注册中心状态管理")
        print("="*60)
        
        return True
        
    except Exception as e:
        print("\n" + "="*60)
        print("❌ 脚本集成测试失败！")
        print("="*60)
        print(f"错误信息: {e}")
        logger.error(f"集成测试失败: {e}", exc_info=True)
        print("="*60)
        
        return False


if __name__ == "__main__":
    # 运行测试
    success = asyncio.run(main())
    sys.exit(0 if success else 1)