#!/usr/bin/env python3
"""真实场景测试：模拟用户使用不同网关的情况"""

import asyncio
import os
import sys
from pathlib import Path
from unittest.mock import Mock, AsyncMock, patch
import json

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

class RealScenarioTests:
    """真实场景测试"""
    
    def __init__(self):
        self.scenarios = []
    
    def add_scenario(self, name, description, test_func):
        """添加测试场景"""
        self.scenarios.append({
            "name": name,
            "description": description,
            "test_func": test_func
        })
    
    async def run_scenario_1_deepseek_openai_gateway(self):
        """场景1: 使用DeepSeek模型（OpenAI网关）"""
        print("\n🔍 场景1: DeepSeek模型 + OpenAI网关")
        print("="*50)
        
        try:
            from core.main_agent import MainAgent
            
            # 模拟依赖
            mock_context = AsyncMock()
            mock_safety = Mock()
            
            # DeepSeek配置
            model_config = {
                "name": "deepseek-chat",
                "gateway": "openai",
                "api_key": "sk-deepseek-test-key",
                "base_url": "https://api.deepseek.com/v1",
                "temperature": 0.1,
                "max_tokens": 1000
            }
            
            print(f"📋 配置: {json.dumps(model_config, indent=2, ensure_ascii=False)}")
            
            # 创建Agent
            with patch('openai.OpenAI') as mock_openai:
                mock_client = Mock()
                mock_openai.return_value = mock_client
                
                # 模拟响应
                mock_stream = Mock()
                mock_chunk = Mock()
                mock_chunk.choices = [Mock()]
                mock_chunk.choices[0].delta = Mock(content="我是DeepSeek助手，很高兴为您服务！")
                mock_stream.__iter__ = Mock(return_value=iter([mock_chunk]))
                mock_client.chat.completions.create.return_value = mock_stream
                
                agent = MainAgent(
                    project_path=Path.cwd(),
                    context_manager=mock_context,
                    safety_guard=mock_safety,
                    model_config=model_config,
                )
                
                print("✅ Agent创建成功")
                print(f"🔧 网关类型: {model_config['gateway']}")
                print(f"🤖 模型名称: {model_config['name']}")
                
                # 测试消息
                test_messages = [
                    {"role": "system", "content": "你是一个编程助手，擅长Python开发。"},
                    {"role": "user", "content": "请写一个Python函数计算斐波那契数列。"}
                ]
                
                print("📝 发送测试消息...")
                response = await agent.model_caller(test_messages)
                print(f"💬 模型响应: {response}")
                
                print("✅ 场景1测试通过")
                return True
                
        except Exception as e:
            print(f"❌ 场景1测试失败: {str(e)}")
            import traceback
            traceback.print_exc()
            return False
    
    async def run_scenario_2_minimax_anthropic_gateway(self):
        """场景2: 使用MiniMax模型（Anthropic网关）"""
        print("\n🔍 场景2: MiniMax模型 + Anthropic网关")
        print("="*50)
        
        try:
            from core.main_agent import MainAgent
            
            # 模拟依赖
            mock_context = AsyncMock()
            mock_safety = Mock()
            
            # MiniMax配置
            model_config = {
                "name": "MiniMax-M2.5",
                "gateway": "anthropic",
                "api_key": "minimax-test-key",
                "base_url": "https://api.minimax.chat/v1",
                "temperature": 0.1,
                "max_tokens": 1000
            }
            
            print(f"📋 配置: {json.dumps(model_config, indent=2, ensure_ascii=False)}")
            
            # 创建Agent
            with patch('anthropic.Anthropic') as mock_anthropic:
                mock_client = Mock()
                mock_anthropic.return_value = mock_client
                mock_messages = Mock()
                mock_client.messages = mock_messages
                
                # 模拟Anthropic流式响应
                mock_stream = Mock()
                mock_stream.text_stream = iter(["我是MiniMax助手，", "支持多模态功能！"])
                mock_stream.__enter__ = Mock(return_value=mock_stream)
                mock_stream.__exit__ = Mock(return_value=None)
                mock_messages.stream.return_value = mock_stream
                
                # 模拟run_in_executor
                with patch('asyncio.get_event_loop') as mock_loop:
                    mock_loop_instance = Mock()
                    mock_loop.return_value = mock_loop_instance
                    
                    def sync_call():
                        result = ""
                        with mock_stream as stream:
                            for text in stream.text_stream:
                                result += text
                        return result
                    
                    mock_loop_instance.run_in_executor.return_value = asyncio.Future()
                    mock_loop_instance.run_in_executor.return_value.set_result("我是MiniMax助手，支持多模态功能！")
                    
                    agent = MainAgent(
                        project_path=Path.cwd(),
                        context_manager=mock_context,
                        safety_guard=mock_safety,
                        model_config=model_config,
                    )
                    
                    print("✅ Agent创建成功")
                    print(f"🔧 网关类型: {model_config['gateway']}")
                    print(f"🤖 模型名称: {model_config['name']}")
                    print("📸 多模态支持: 是")
                    
                    # 测试消息
                    test_messages = [
                        {"role": "system", "content": "你是一个多模态助手，可以处理图像和文本。"},
                        {"role": "user", "content": "请描述这张图片中的内容。"}
                    ]
                    
                    print("📝 发送测试消息...")
                    response = await agent.model_caller(test_messages)
                    print(f"💬 模型响应: {response}")
                    
                    print("✅ 场景2测试通过")
                    return True
                
        except Exception as e:
            print(f"❌ 场景2测试失败: {str(e)}")
            import traceback
            traceback.print_exc()
            return False
    
    async def run_scenario_3_kimi_openai_gateway(self):
        """场景3: 使用Kimi模型（OpenAI网关）"""
        print("\n🔍 场景3: Kimi模型 + OpenAI网关")
        print("="*50)
        
        try:
            from core.main_agent import MainAgent
            
            # 模拟依赖
            mock_context = AsyncMock()
            mock_safety = Mock()
            
            # Kimi配置
            model_config = {
                "name": "kimi-k2.5",
                "gateway": "openai",
                "api_key": "sk-kimi-test-key",
                "base_url": "https://api.moonshot.cn/v1",
                "temperature": 0.1,
                "max_tokens": 1000
            }
            
            print(f"📋 配置: {json.dumps(model_config, indent=2, ensure_ascii=False)}")
            
            # 创建Agent
            with patch('openai.OpenAI') as mock_openai:
                mock_client = Mock()
                mock_openai.return_value = mock_client
                
                # 模拟响应
                mock_stream = Mock()
                mock_chunk = Mock()
                mock_chunk.choices = [Mock()]
                mock_chunk.choices[0].delta = Mock(content="我是Kimi助手，擅长长文本理解和分析！")
                mock_stream.__iter__ = Mock(return_value=iter([mock_chunk]))
                mock_client.chat.completions.create.return_value = mock_stream
                
                agent = MainAgent(
                    project_path=Path.cwd(),
                    context_manager=mock_context,
                    safety_guard=mock_safety,
                    model_config=model_config,
                )
                
                print("✅ Agent创建成功")
                print(f"🔧 网关类型: {model_config['gateway']}")
                print(f"🤖 模型名称: {model_config['name']}")
                print("📖 长文本支持: 是")
                
                # 测试消息
                test_messages = [
                    {"role": "system", "content": "你是一个擅长处理长文档的助手。"},
                    {"role": "user", "content": "请总结这篇长文档的主要内容。"}
                ]
                
                print("📝 发送测试消息...")
                response = await agent.model_caller(test_messages)
                print(f"💬 模型响应: {response}")
                
                print("✅ 场景3测试通过")
                return True
                
        except Exception as e:
            print(f"❌ 场景3测试失败: {str(e)}")
            import traceback
            traceback.print_exc()
            return False
    
    async def run_scenario_4_gateway_fallback(self):
        """场景4: 网关后备机制测试"""
        print("\n🔍 场景4: Anthropic网关失败时的OpenAI后备")
        print("="*50)
        
        try:
            from core.main_agent import MainAgent
            
            # 模拟依赖
            mock_context = AsyncMock()
            mock_safety = Mock()
            
            # MiniMax配置（但模拟失败）
            model_config = {
                "name": "MiniMax-M2.5",
                "gateway": "anthropic",
                "api_key": "invalid-key",
                "base_url": "https://api.minimax.chat/v1",
                "temperature": 0.1,
                "max_tokens": 1000
            }
            
            print(f"📋 配置: {json.dumps(model_config, indent=2, ensure_ascii=False)}")
            print("⚠️  模拟Anthropic网关失败，触发后备机制...")
            
            # 创建Agent
            with patch('anthropic.Anthropic') as mock_anthropic:
                mock_client = Mock()
                mock_anthropic.return_value = mock_client
                mock_messages = Mock()
                mock_client.messages = mock_messages
                
                # 模拟Anthropic失败
                mock_messages.stream.side_effect = Exception("404 page not found")
                
                # 模拟OpenAI成功响应（后备）
                with patch('openai.OpenAI') as mock_openai:
                    mock_openai_client = Mock()
                    mock_openai.return_value = mock_openai_client
                    
                    mock_stream = Mock()
                    mock_chunk = Mock()
                    mock_chunk.choices = [Mock()]
                    mock_chunk.choices[0].delta = Mock(content="我是OpenAI后备助手！")
                    mock_stream.__iter__ = Mock(return_value=iter([mock_chunk]))
                    mock_openai_client.chat.completions.create.return_value = mock_stream
                    
                    agent = MainAgent(
                        project_path=Path.cwd(),
                        context_manager=mock_context,
                        safety_guard=mock_safety,
                        model_config=model_config,
                    )
                    
                    print("✅ Agent创建成功")
                    
                    # 测试消息
                    test_messages = [
                        {"role": "user", "content": "测试后备机制"}
                    ]
                    
                    print("📝 发送测试消息...")
                    response = await agent.model_caller(test_messages)
                    print(f"💬 模型响应: {response}")
                    
                    if "后备" in response:
                        print("✅ 场景4测试通过 - 成功触发后备机制")
                        return True
                    else:
                        print("❌ 场景4测试失败 - 未正确触发后备")
                        return False
                
        except Exception as e:
            print(f"❌ 场景4测试失败: {str(e)}")
            import traceback
            traceback.print_exc()
            return False
    
    async def run_scenario_5_auto_detection(self):
        """场景5: 模型自动检测测试"""
        print("\n🔍 场景5: 模型名称自动检测网关")
        print("="*50)
        
        try:
            from config import Settings
            
            test_cases = [
                ("deepseek-chat", "openai", "DeepSeek"),
                ("MiniMax-M2.5", "anthropic", "MiniMax"),
                ("kimi-k2.5", "openai", "Kimi"),
                ("gpt-4-turbo", "openai", "GPT-4"),
            ]
            
            print("🧪 测试模型自动检测:")
            print("-"*40)
            
            all_passed = True
            for model_name, expected_gateway, model_display in test_cases:
                # 设置环境变量
                os.environ["LLM_MODEL_NAME"] = model_name
                os.environ.pop("LLM_GATEWAY", None)
                
                # 重新加载配置
                settings = Settings()
                
                if settings.model.gateway == expected_gateway:
                    print(f"  ✅ {model_display} ({model_name}): 正确检测为 {expected_gateway} 网关")
                else:
                    print(f"  ❌ {model_display} ({model_name}): 期望 {expected_gateway}, 实际 {settings.model.gateway}")
                    all_passed = False
            
            if all_passed:
                print("✅ 场景5测试通过 - 所有模型自动检测正确")
                return True
            else:
                print("❌ 场景5测试失败 - 部分模型检测不正确")
                return False
                
        except Exception as e:
            print(f"❌ 场景5测试失败: {str(e)}")
            import traceback
            traceback.print_exc()
            return False
    
    async def run_all_scenarios(self):
        """运行所有场景测试"""
        print("🚀 开始真实场景测试")
        print("="*60)
        
        scenarios = [
            ("DeepSeek + OpenAI网关", self.run_scenario_1_deepseek_openai_gateway),
            ("MiniMax + Anthropic网关", self.run_scenario_2_minimax_anthropic_gateway),
            ("Kimi + OpenAI网关", self.run_scenario_3_kimi_openai_gateway),
            ("网关后备机制", self.run_scenario_4_gateway_fallback),
            ("模型自动检测", self.run_scenario_5_auto_detection),
        ]
        
        results = []
        for name, test_func in scenarios:
            print(f"\n📋 场景: {name}")
            success = await test_func()
            results.append((name, success))
        
        # 打印摘要
        print("\n" + "="*60)
        print("真实场景测试摘要")
        print("="*60)
        
        passed = 0
        failed = 0
        for name, success in results:
            status = "✅" if success else "❌"
            print(f"{status} {name}")
            if success:
                passed += 1
            else:
                failed += 1
        
        print("\n" + "="*60)
        print(f"总计: {len(results)} 个场景")
        print(f"通过: {passed}")
        print(f"失败: {failed}")
        print("="*60)
        
        if failed == 0:
            print("\n🎉 所有真实场景测试通过！")
            return True
        else:
            print("\n⚠️  部分场景测试失败，请检查问题。")
            return False

async def main():
    """主函数"""
    tester = RealScenarioTests()
    success = await tester.run_all_scenarios()
    
    return 0 if success else 1

if __name__ == "__main__":
    # 清理环境变量
    env_vars_to_clear = [
        "LLM_API_KEY", "OPENAI_API_KEY", "LLM_GATEWAY",
        "LLM_MODEL_NAME", "LLM_API_URL", "SEARCHXNG_URL"
    ]
    
    for var in env_vars_to_clear:
        os.environ.pop(var, None)
    
    exit_code = asyncio.run(main())
    sys.exit(exit_code)