"""
智能算法展示平台 - 系统集成测试套件

此测试套件验证整个系统的功能完整性，包括：
- API网关功能
- 算法注册和管理
- 算法调用流程
- 数据管理
- 用户认证和权限
- 监控和日志
- 服务发现和管理
"""

import os
import sys
import unittest
import asyncio
import requests
import time
from datetime import datetime, timedelta
from typing import Dict, Any, Optional

# 添加项目根目录到路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from backend.app.services.service_manager import ServiceManager
from backend.app.services.data_manager import DataManager
from backend.app.services.monitoring import MonitoringService
from backend.app.services.permission import PermissionManager


class IntegrationTestBase(unittest.TestCase):
    """集成测试基类"""
    
    @classmethod
    def setUpClass(cls):
        """在所有测试开始前设置"""
        cls.base_url = os.getenv('TEST_BASE_URL', 'http://localhost:8001')
        cls.api_key = os.getenv('TEST_API_KEY', 'test-key-12345')
        cls.headers = {
            'Authorization': f'Bearer {cls.api_key}',
            'Content-Type': 'application/json'
        }
        cls.test_algorithm_id = 'test-alg-' + str(int(time.time()))
        cls.test_user_id = 'test-user-' + str(int(time.time()))
        
    def setUp(self):
        """每个测试开始前设置"""
        self.session = requests.Session()
        self.session.headers.update(self.headers)
        
    def tearDown(self):
        """每个测试结束后清理"""
        self.session.close()


class TestAlgorithmManagement(IntegrationTestBase):
    """算法管理功能集成测试"""
    
    def test_create_and_get_algorithm(self):
        """测试创建和获取算法"""
        # 创建算法
        algorithm_data = {
            'name': f'Test Algorithm {self.test_algorithm_id}',
            'description': 'Test algorithm for integration testing',
            'type': 'computer_vision',
            'status': 'active'
        }
        
        response = self.session.post(
            f'{self.base_url}/api/v1/algorithms',
            json=algorithm_data
        )
        
        self.assertEqual(response.status_code, 200)
        created_alg = response.json()
        self.assertEqual(created_alg['name'], algorithm_data['name'])
        self.assertEqual(created_alg['type'], algorithm_data['type'])
        
        # 获取刚创建的算法
        response = self.session.get(
            f'{self.base_url}/api/v1/algorithms/{created_alg["id"]}'
        )
        
        self.assertEqual(response.status_code, 200)
        retrieved_alg = response.json()
        self.assertEqual(retrieved_alg['id'], created_alg['id'])
        self.assertEqual(retrieved_alg['name'], created_alg['name'])
        
    def test_list_algorithms(self):
        """测试获取算法列表"""
        response = self.session.get(f'{self.base_url}/api/v1/algorithms')
        
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIn('algorithms', data)
        self.assertIn('total', data)
        self.assertIsInstance(data['algorithms'], list)


class TestAlgorithmCallFlow(IntegrationTestBase):
    """算法调用流程集成测试"""
    
    def setUp(self):
        super().setUp()
        
        # 创建一个测试算法
        algorithm_data = {
            'name': f'Test Call Algorithm {self.test_algorithm_id}',
            'description': 'Test algorithm for call flow testing',
            'type': 'computer_vision',
            'status': 'active'
        }
        
        response = self.session.post(
            f'{self.base_url}/api/v1/algorithms',
            json=algorithm_data
        )
        
        self.assertEqual(response.status_code, 200)
        self.created_algorithm = response.json()
        
    def test_algorithm_call_process(self):
        """测试完整的算法调用流程"""
        # 调用算法
        call_data = {
            'algorithm_id': self.created_algorithm['id'],
            'version_id': self.created_algorithm['versions'][0]['id'] if self.created_algorithm['versions'] else None,
            'input_data': {
                'image_url': 'https://example.com/test-image.jpg'
            },
            'params': {
                'confidence_threshold': 0.7
            }
        }
        
        response = self.session.post(
            f'{self.base_url}/api/v1/algorithms/call',
            json=call_data
        )
        
        self.assertEqual(response.status_code, 200)
        call_result = response.json()
        self.assertIn('id', call_result)
        self.assertIn('status', call_result)
        self.assertIn('output_data', call_result)
        
        # 获取调用结果
        response = self.session.get(
            f'{self.base_url}/api/v1/algorithms/calls/{call_result["id"]}'
        )
        
        self.assertEqual(response.status_code, 200)
        retrieved_result = response.json()
        self.assertEqual(retrieved_result['id'], call_result['id'])
        self.assertEqual(retrieved_result['status'], call_result['status'])


class TestGatewayFunctionality(IntegrationTestBase):
    """API网关功能集成测试"""
    
    def setUp(self):
        super().setUp()
        
        # 创建一个测试算法
        algorithm_data = {
            'name': f'Test Gateway Algorithm {self.test_algorithm_id}',
            'description': 'Test algorithm for gateway testing',
            'type': 'computer_vision',
            'status': 'active'
        }
        
        response = self.session.post(
            f'{self.base_url}/api/v1/algorithms',
            json=algorithm_data
        )
        
        self.assertEqual(response.status_code, 200)
        self.created_algorithm = response.json()
        
    def test_gateway_call(self):
        """测试通过网关调用算法"""
        # 通过网关调用算法
        call_data = {
            'algorithm_id': self.created_algorithm['id'],
            'version_id': self.created_algorithm['versions'][0]['id'] if self.created_algorithm['versions'] else None,
            'input_data': {
                'image_url': 'https://example.com/test-image.jpg'
            },
            'params': {
                'confidence_threshold': 0.7
            }
        }
        
        response = self.session.post(
            f'{self.base_url}/api/v1/gateway/call',
            json=call_data
        )
        
        self.assertEqual(response.status_code, 200)
        gateway_result = response.json()
        self.assertIn('id', gateway_result)
        self.assertIn('status', gateway_result)
        self.assertIn('response_time', gateway_result)
        
    def test_gateway_stats(self):
        """测试网关统计信息"""
        response = self.session.get(f'{self.base_url}/api/v1/gateway/stats')
        
        self.assertEqual(response.status_code, 200)
        stats = response.json()
        self.assertIn('total_requests', stats)
        self.assertIn('successful_requests', stats)
        self.assertIn('failed_requests', stats)


class TestDataService(IntegrationTestBase):
    """数据服务集成测试"""
    
    def test_data_storage_and_retrieval(self):
        """测试数据存储和检索"""
        # 使用数据管理服务
        data_manager = DataManager()
        
        # 存储输入数据
        input_data = {'image_url': 'https://example.com/test.jpg'}
        input_id = data_manager.save_input_data(input_data)
        self.assertIsNotNone(input_id)
        
        # 存储输出数据
        output_data = {
            'predictions': [
                {'class': 'cat', 'confidence': 0.95},
                {'class': 'dog', 'confidence': 0.87}
            ]
        }
        output_id = data_manager.save_output_data(output_data)
        self.assertIsNotNone(output_id)
        
        # 检索数据
        retrieved_input = data_manager.get_input_data(input_id)
        self.assertEqual(retrieved_input, input_data)
        
        retrieved_output = data_manager.get_output_data(output_id)
        self.assertEqual(retrieved_output, output_data)


class TestMonitoringService(IntegrationTestBase):
    """监控服务集成测试"""
    
    def test_monitoring_functionality(self):
        """测试监控功能"""
        monitoring_service = MonitoringService()
        
        # 检查健康状态
        health_status = monitoring_service.get_health_status()
        self.assertIsNotNone(health_status)
        self.assertIn('status', health_status)
        self.assertIn('timestamp', health_status)
        self.assertIn('system_metrics', health_status)
        
        # 收集一些指标
        metrics_collector = monitoring_service.metrics_collector
        metrics_collector.record_api_call('test_endpoint', 1.23, 200)
        metrics_collector.record_algorithm_execution('test_alg', 0.98, 'success')
        
        # 获取指标
        metrics = metrics_collector.get_current_metrics()
        self.assertIsNotNone(metrics)


class TestPermissionsService(IntegrationTestBase):
    """权限服务集成测试"""
    
    def test_permission_management(self):
        """测试权限管理"""
        permission_manager = PermissionManager()
        
        # 检查权限
        has_permission = permission_manager.check_permission(
            user_id=self.test_user_id,
            algorithm_id='test-algorithm-123',
            permission_type='execute'
        )
        
        # 可能没有权限，但至少方法应该不抛异常
        self.assertIsInstance(has_permission, bool)
        
        # 添加权限
        permission_manager.grant_permission(
            user_id=self.test_user_id,
            algorithm_id='test-algorithm-123',
            permission_type='execute'
        )
        
        # 再次检查权限
        has_permission_after = permission_manager.check_permission(
            user_id=self.test_user_id,
            algorithm_id='test-algorithm-123',
            permission_type='execute'
        )
        
        self.assertTrue(has_permission_after)


class TestServiceManagement(IntegrationTestBase):
    """服务管理集成测试"""
    
    def test_service_registration_and_discovery(self):
        """测试服务注册和发现"""
        service_manager = ServiceManager()
        
        # 注册一个测试服务
        service_info = {
            'name': f'test-service-{int(time.time())}',
            'host': 'localhost',
            'port': 8080,
            'protocol': 'http',
            'metadata': {'version': '1.0.0'}
        }
        
        registered_service = service_manager.register_service(service_info)
        self.assertIsNotNone(registered_service)
        
        # 发现服务
        discovered_services = service_manager.discover_services(service_info['name'])
        self.assertIn(registered_service['id'], [s['id'] for s in discovered_services])
        
        # 检查服务状态
        service_status = service_manager.get_service_status(registered_service['id'])
        self.assertIsNotNone(service_status)


class TestHistoryManagement(IntegrationTestBase):
    """历史记录管理集成测试"""
    
    def test_history_operations(self):
        """测试历史记录操作"""
        # 先调用一个算法来生成历史记录
        algorithm_data = {
            'name': f'Test History Algorithm {self.test_algorithm_id}',
            'description': 'Test algorithm for history testing',
            'type': 'computer_vision',
            'status': 'active'
        }
        
        response = self.session.post(
            f'{self.base_url}/api/v1/algorithms',
            json=algorithm_data
        )
        
        self.assertEqual(response.status_code, 200)
        created_algorithm = response.json()
        
        # 调用算法
        call_data = {
            'algorithm_id': created_algorithm['id'],
            'version_id': created_algorithm['versions'][0]['id'] if created_algorithm['versions'] else None,
            'input_data': {'test': 'data'},
            'params': {}
        }
        
        response = self.session.post(
            f'{self.base_url}/api/v1/algorithms/call',
            json=call_data
        )
        
        self.assertEqual(response.status_code, 200)
        call_result = response.json()
        
        # 获取历史记录
        response = self.session.get(f'{self.base_url}/api/v1/history/user-calls')
        
        self.assertEqual(response.status_code, 200)
        history_data = response.json()
        self.assertIn('history', history_data)
        self.assertIn('count', history_data)
        
        # 获取统计信息
        response = self.session.get(f'{self.base_url}/api/v1/history/statistics')
        
        self.assertEqual(response.status_code, 200)
        stats_data = response.json()
        self.assertIn('total_calls', stats_data)
        self.assertIn('success_rate', stats_data)


class TestOpenAIFunctionality(IntegrationTestBase):
    """OpenAI集成功能测试"""
    
    def test_openai_integration(self):
        """测试OpenAI集成"""
        # 检查是否设置了OpenAI API密钥
        openai_api_key = os.getenv('OPENAI_API_KEY')
        if not openai_api_key:
            self.skipTest("OPENAI_API_KEY not set, skipping OpenAI integration test")
        
        # 生成仿真数据
        generation_data = {
            'prompt': '一个包含猫和狗的图像描述',
            'data_type': 'text'
        }
        
        response = self.session.post(
            f'{self.base_url}/api/v1/openai/generate-data',
            json=generation_data
        )
        
        # 即使API密钥无效，也应该返回合理的错误而不是崩溃
        self.assertIn(response.status_code, [200, 401, 500])
        
        if response.status_code == 200:
            result = response.json()
            self.assertIn('data', result)
            self.assertIn('type', result)


class TestFullWorkflow(IntegrationTestBase):
    """完整工作流程集成测试"""
    
    def test_complete_workflow(self):
        """测试完整的端到端工作流程"""
        # 1. 创建算法
        algorithm_data = {
            'name': f'Complete Workflow Test {self.test_algorithm_id}',
            'description': 'Algorithm for complete workflow testing',
            'type': 'nlp',
            'status': 'active'
        }
        
        response = self.session.post(
            f'{self.base_url}/api/v1/algorithms',
            json=algorithm_data
        )
        
        self.assertEqual(response.status_code, 200)
        created_algorithm = response.json()
        self.assertIsNotNone(created_algorithm['id'])
        
        # 2. 通过网关调用算法
        call_data = {
            'algorithm_id': created_algorithm['id'],
            'version_id': created_algorithm['versions'][0]['id'] if created_algorithm['versions'] else None,
            'input_data': {
                'text': '这是一个测试文本'
            },
            'params': {
                'max_length': 100
            }
        }
        
        response = self.session.post(
            f'{self.base_url}/api/v1/gateway/call',
            json=call_data
        )
        
        self.assertEqual(response.status_code, 200)
        gateway_result = response.json()
        self.assertIsNotNone(gateway_result['id'])
        self.assertIn('status', gateway_result)
        
        # 3. 验证调用已记录到历史
        response = self.session.get(
            f'{self.base_url}/api/v1/history/user-calls',
            params={'limit': 10}
        )
        
        self.assertEqual(response.status_code, 200)
        history_data = response.json()
        self.assertGreater(len(history_data['history']), 0)
        
        # 4. 检查监控指标
        response = self.session.get(f'{self.base_url}/api/v1/monitoring/health')
        self.assertEqual(response.status_code, 200)
        
        # 5. 获取算法性能指标
        response = self.session.get(
            f'{self.base_url}/api/v1/monitoring/performance/algorithm/{created_algorithm["id"]}'
        )
        self.assertIn(response.status_code, [200, 404])  # 404可能表示没有足够的数据


def run_integration_tests():
    """运行所有集成测试"""
    # 创建测试套件
    loader = unittest.TestLoader()
    suite = unittest.TestSuite()
    
    # 添加所有测试类
    test_classes = [
        TestAlgorithmManagement,
        TestAlgorithmCallFlow,
        TestGatewayFunctionality,
        TestDataService,
        TestMonitoringService,
        TestPermissionsService,
        TestServiceManagement,
        TestHistoryManagement,
        TestOpenAIFunctionality,
        TestFullWorkflow
    ]
    
    for test_class in test_classes:
        tests = loader.loadTestsFromTestCase(test_class)
        suite.addTests(tests)
    
    # 运行测试
    runner = unittest.TextTestRunner(verbosity=2)
    result = runner.run(suite)
    
    return result.wasSuccessful()


if __name__ == '__main__':
    print("开始运行智能算法展示平台集成测试...")
    print("=" * 60)
    
    success = run_integration_tests()
    
    print("=" * 60)
    if success:
        print("✅ 所有集成测试通过！")
        sys.exit(0)
    else:
        print("❌ 部分集成测试失败！")
        sys.exit(1)