"""
系统升级迁移测试用例
测试系统升级过程中的数据迁移和兼容性
"""

import pytest
import asyncio
import time
from api.user_api import UserAPI
from api.role_api import RoleAPI
from api.config_api import SysConfigAPI


@pytest.mark.migration
@pytest.mark.regression
@pytest.mark.critical
class TestSystemMigration:
    """系统升级迁移测试类"""
    
    @pytest.mark.asyncio
    async def test_user_data_migration(self, authenticated_client, test_data_manager):
        """测试用户数据迁移"""
        user_api = UserAPI(authenticated_client)
        
        unique_id = f"{int(time.time() * 1000)}"
        
        # 创建旧版本用户数据
        old_user_data = {
            "username": f"old_user_{unique_id}",
            "password": "Test123!@#",
            "email": f"old_{unique_id}@example.com",
            "status": 1
        }
        
        create_response = await user_api.create_user(old_user_data)
        assert create_response.status_code == 201
        user_id = create_response.json()["id"]
        test_data_manager.add_user(user_id)
        
        # 模拟数据迁移：更新用户邮箱（模拟数据迁移场景）
        migrated_email = f"migrated_{unique_id}@example.com"
        
        # 执行迁移（更新用户数据）
        migrate_response = await user_api.update_user(user_id, {
            "email": migrated_email
        })
        assert migrate_response.status_code == 200
        
        # 验证迁移成功
        migrated_user = await user_api.get_user_by_id(user_id)
        user_data = migrated_user.json()
        assert user_data["username"] == old_user_data["username"]
        assert user_data["email"] == migrated_email
    
    @pytest.mark.asyncio
    async def test_role_permission_migration(self, authenticated_client, test_data_manager):
        """测试角色权限迁移"""
        role_api = RoleAPI(authenticated_client)
        
        unique_id = f"{int(time.time() * 1000)}"
        
        # 创建旧版本角色
        old_role_data = {
            "roleName": f"Old_Role_{unique_id}",
            "roleKey": f"old_role_{unique_id}",
            "roleSort": 1,
            "status": 1
        }
        
        create_response = await role_api.create_role(old_role_data)
        assert create_response.status_code == 201
        role_id = create_response.json()["id"]
        test_data_manager.add_role(role_id)
        
        # 模拟权限迁移：更新角色信息
        migrated_role_data = {
            "roleName": f"New_Role_{unique_id}",  # 更新名称
            "roleKey": f"new_role_{unique_id}",  # 更新key
            "roleSort": 10,  # 更新排序
            "status": 1,
            "remark": "迁移后的角色"  # 新增备注
        }
        
        # 执行迁移
        migrate_response = await role_api.update_role(role_id, {
            "roleName": migrated_role_data["roleName"],
            "roleKey": migrated_role_data["roleKey"],
            "roleSort": migrated_role_data["roleSort"],
            "remark": migrated_role_data["remark"]
        })
        assert migrate_response.status_code == 200
        
        # 验证迁移成功
        migrated_role = await role_api.get_role_by_id(role_id)
        role_data = migrated_role.json()
        assert role_data["roleName"] == migrated_role_data["roleName"]
        assert role_data["roleKey"] == migrated_role_data["roleKey"]
        assert role_data["roleSort"] == migrated_role_data["roleSort"]
        if "remark" in role_data:
            assert role_data["remark"] == migrated_role_data["remark"]
    
    @pytest.mark.asyncio
    async def test_config_data_migration(self, authenticated_client):
        """测试配置数据迁移"""
        config_api = SysConfigAPI(authenticated_client)
        
        unique_id = f"{int(time.time() * 1000)}"
        
        # 创建旧版本配置
        old_config_data = {
            "configName": f"Old_Config_{unique_id}",
            "configKey": f"old_config_{unique_id}",
            "configValue": "old_value",
            "configType": "Y"
        }
        
        create_response = await config_api.create(old_config_data)
        assert create_response.status_code in [200, 201]
        config_id = create_response.json().get("id") or create_response.json().get("configId")
        
        # 模拟配置迁移：更新配置值
        new_config_value = "new_value"
        
        # 执行迁移
        if config_id:
            migrate_response = await config_api.update(config_id, {
                "configValue": new_config_value
            })
            # 如果更新失败，可能是配置不存在或权限问题，跳过验证
            if migrate_response.status_code == 200:
                # 验证迁移成功 - 获取所有配置并查找我们的配置
                all_configs = await config_api.get_all()
                assert all_configs.status_code == 200
                configs_list = all_configs.json()
                
                # 查找迁移后的配置
                found_config = None
                for config in configs_list:
                    if config.get("configKey") == old_config_data["configKey"]:
                        found_config = config
                        break
                
                assert found_config is not None, "迁移后的配置未找到"
                assert found_config["configValue"] == new_config_value
    
    @pytest.mark.asyncio
    async def test_backward_compatibility(self, authenticated_client, test_data_manager):
        """测试向后兼容性"""
        user_api = UserAPI(authenticated_client)
        
        unique_id = f"{int(time.time() * 1000)}"
        
        # 创建用户（模拟旧版本数据）
        user_data = {
            "username": f"compat_user_{unique_id}",
            "password": "Test123!@#",
            "email": f"compat_{unique_id}@example.com",
            "status": 1
        }
        
        create_response = await user_api.create_user(user_data)
        assert create_response.status_code == 201
        user_id = create_response.json()["id"]
        test_data_manager.add_user(user_id)
        
        # 使用旧版本API调用方式（只传递必需字段）
        update_response = await user_api.update_user(user_id, {
            "email": f"updated_{unique_id}@example.com"
        })
        assert update_response.status_code == 200
        
        # 验证旧版本调用仍然有效
        user_verify = await user_api.get_user_by_id(user_id)
        assert user_verify.status_code == 200
        assert user_verify.json()["email"] == f"updated_{unique_id}@example.com"