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

import os
import sys
import logging
import asyncio
import time
from datetime import datetime

# 添加项目根目录到路径，确保可以导入核心模块
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from core.ai_agent import AI_Agent, Timeout

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[logging.StreamHandler()]
)

# 从环境变量获取API密钥，或使用默认值
API_KEY = os.environ.get("OPENAI_API_KEY", "your_api_key_here")
# 使用API的基础URL
BASE_URL = os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1")
# 使用的模型名称
MODEL_NAME = os.environ.get("OPENAI_MODEL", "gpt-3.5-turbo")

def print_with_timestamp(message, end='\n'):
    """打印带有时间戳和线程ID的消息"""
    timestamp = datetime.now().strftime("%H:%M:%S")
    task_id = asyncio.current_task().get_name() if asyncio.current_task() else "主线程"
    print(f"[{timestamp}][{task_id}] {message}", end=end, flush=True)

async def process_stream_task(agent, system_prompt, user_prompt, task_id):
    """处理单个流式生成任务"""
    print_with_timestamp(f"任务 {task_id} 开始")
    start_time = time.time()
    
    try:
        full_response = ""
        async for chunk in agent.async_generate_text_stream(
            system_prompt=system_prompt,
            user_prompt=user_prompt
        ):
            full_response += chunk
            print_with_timestamp(f"任务 {task_id} 收到块: 「{chunk}」", end="")
        
        elapsed = time.time() - start_time
        print_with_timestamp(f"\n任务 {task_id} 完成！耗时: {elapsed:.2f}秒")
        return {"task_id": task_id, "response": full_response, "success": True, "elapsed": elapsed}
    
    except Timeout as e:
        elapsed = time.time() - start_time
        print_with_timestamp(f"任务 {task_id} 超时: {e}")
        return {"task_id": task_id, "error": str(e), "success": False, "elapsed": elapsed}
    
    except Exception as e:
        elapsed = time.time() - start_time
        print_with_timestamp(f"任务 {task_id} 异常: {type(e).__name__} - {e}")
        return {"task_id": task_id, "error": f"{type(e).__name__}: {str(e)}", "success": False, "elapsed": elapsed}

async def run_concurrent_streams():
    """同时运行多个流式生成任务"""
    print_with_timestamp("开始并发流式处理测试...")
    
    # 创建 AI_Agent 实例
    agent = AI_Agent(
        base_url=BASE_URL,
        model_name=MODEL_NAME,
        api=API_KEY,
        timeout=30,  # 请求总超时时间
        max_retries=2,  
        stream_chunk_timeout=10  # 流块超时时间
    )
    
    try:
        # 定义不同的任务
        tasks = [
            {
                "id": "城市介绍",
                "system": "你是一个专业的旅游指南。",
                "user": "请简要介绍北京这座城市的历史和主要景点。"
            },
            {
                "id": "美食推荐",
                "system": "你是一个美食专家。",
                "user": "推荐5种上海的特色小吃，并简要说明其特点。"
            },
            {
                "id": "旅行建议",
                "system": "你是一个旅行规划顾问。",
                "user": "我计划去云南旅行一周，请给我一个简要的行程安排。"
            }
        ]
        
        start_time = time.time()
        
        # 创建并发任务
        coroutines = []
        for task in tasks:
            # 为每个任务设置不同名称，便于日志区分
            coro = process_stream_task(
                agent=agent,
                system_prompt=task["system"],
                user_prompt=task["user"],
                task_id=task["id"]
            )
            # 设置任务名称
            coroutines.append(asyncio.create_task(coro, name=f"Task-{task['id']}"))
        
        # 等待所有任务完成
        results = await asyncio.gather(*coroutines, return_exceptions=True)
        
        # 处理并显示结果
        total_elapsed = time.time() - start_time
        print_with_timestamp(f"所有任务完成，总耗时: {total_elapsed:.2f}秒")
        
        success_count = sum(1 for r in results if isinstance(r, dict) and r.get("success", False))
        error_count = len(results) - success_count
        
        print_with_timestamp(f"成功任务: {success_count}, 失败任务: {error_count}")
        
        # 显示每个任务的详细结果
        for i, result in enumerate(results):
            if isinstance(result, dict):
                task_id = result.get("task_id", f"未知任务-{i}")
                if result.get("success", False):
                    print_with_timestamp(f"任务 {task_id} 成功，耗时: {result.get('elapsed', 0):.2f}秒")
                else:
                    print_with_timestamp(f"任务 {task_id} 失败: {result.get('error', '未知错误')}")
            else:
                print_with_timestamp(f"任务 {i} 返回了异常: {result}")
    
    except Exception as e:
        print_with_timestamp(f"并发处理主程序异常: {type(e).__name__} - {e}")
    
    finally:
        # 关闭 AI_Agent
        agent.close()

async def run_sequential_vs_concurrent():
    """比较顺序处理和并发处理的性能差异"""
    print_with_timestamp("开始顺序处理与并发处理性能对比测试...")
    
    # 创建 AI_Agent 实例
    agent = AI_Agent(
        base_url=BASE_URL,
        model_name=MODEL_NAME,
        api=API_KEY,
        timeout=30,
        max_retries=2,
        stream_chunk_timeout=10
    )
    
    # 定义测试任务
    tasks = [
        {"id": "任务1", "prompt": "列出三个世界著名的旅游景点及其特色。"},
        {"id": "任务2", "prompt": "简述三种不同的旅行方式的优缺点。"},
        {"id": "任务3", "prompt": "推荐三个适合冬季旅行的目的地。"}
    ]
    
    try:
        # 顺序处理
        print_with_timestamp("开始顺序处理...")
        sequential_start = time.time()
        
        for task in tasks:
            print_with_timestamp(f"开始处理 {task['id']}...")
            task_start = time.time()
            
            try:
                response = ""
                async for chunk in agent.async_generate_text_stream(
                    system_prompt="你是一个旅游顾问。",
                    user_prompt=task["prompt"]
                ):
                    response += chunk
                
                task_elapsed = time.time() - task_start
                print_with_timestamp(f"{task['id']} 完成，耗时: {task_elapsed:.2f}秒")
            
            except Exception as e:
                print_with_timestamp(f"{task['id']} 处理失败: {e}")
        
        sequential_elapsed = time.time() - sequential_start
        print_with_timestamp(f"顺序处理总耗时: {sequential_elapsed:.2f}秒")
        
        # 并发处理
        print_with_timestamp("\n开始并发处理...")
        concurrent_start = time.time()
        
        coroutines = []
        for task in tasks:
            coro = process_stream_task(
                agent=agent,
                system_prompt="你是一个旅游顾问。",
                user_prompt=task["prompt"],
                task_id=task["id"]
            )
            coroutines.append(asyncio.create_task(coro, name=f"Task-{task['id']}"))
        
        await asyncio.gather(*coroutines)
        
        concurrent_elapsed = time.time() - concurrent_start
        print_with_timestamp(f"并发处理总耗时: {concurrent_elapsed:.2f}秒")
        
        # 性能对比
        speedup = sequential_elapsed / concurrent_elapsed if concurrent_elapsed > 0 else float('inf')
        print_with_timestamp(f"\n性能对比:")
        print_with_timestamp(f"顺序处理耗时: {sequential_elapsed:.2f}秒")
        print_with_timestamp(f"并发处理耗时: {concurrent_elapsed:.2f}秒")
        print_with_timestamp(f"加速比: {speedup:.2f}x")
    
    except Exception as e:
        print_with_timestamp(f"对比测试异常: {type(e).__name__} - {e}")
    
    finally:
        agent.close()

if __name__ == "__main__":
    # 运行并发处理示例
    asyncio.run(run_concurrent_streams())
    
    print("\n" + "="*70 + "\n")
    
    # 运行性能对比
    asyncio.run(run_sequential_vs_concurrent()) 