"""
分布式事务一致性测试用例
测试跨模块业务操作的数据一致性
"""

import pytest
import asyncio
import time
from api.user_api import UserAPI
from api.role_api import RoleAPI
from api.notice_api import SysNoticeAPI


@pytest.mark.distributed
@pytest.mark.regression
@pytest.mark.critical
class TestDistributedTransaction:
    """分布式事务一致性测试类"""
    
    @pytest.mark.asyncio
    async def test_user_role_assignment_consistency(self, authenticated_client, test_data_manager):
        """测试用户角色分配的事务一致性"""
        user_api = UserAPI(authenticated_client)
        role_api = RoleAPI(authenticated_client)
        
        unique_id = f"{int(time.time() * 1000)}"
        
        # 创建角色
        role_data = {
            "roleName": f"TX_Role_{unique_id}",
            "roleKey": f"tx_role_{unique_id}",
            "roleSort": 1,
            "status": 1
        }
        
        role_response = await role_api.create_role(role_data)
        assert role_response.status_code == 201
        role_id = role_response.json()["id"]
        test_data_manager.add_role(role_id)
        
        # 创建用户
        user_data = {
            "username": f"tx_user_{unique_id}",
            "password": "Test123!@#",
            "email": f"tx_{unique_id}@example.com",
            "status": 1
        }
        
        user_response = await user_api.create_user(user_data)
        assert user_response.status_code == 201
        user_id = user_response.json()["id"]
        test_data_manager.add_user(user_id)
        
        # 分配角色
        assign_response = await user_api.update_user(user_id, {"roleId": role_id})
        assert assign_response.status_code == 200
        
        # 验证一致性
        user_verify = await user_api.get_user_by_id(user_id)
        assert user_verify.json()["roleId"] == role_id
        
        role_verify = await role_api.get_role_by_id(role_id)
        assert role_verify.status_code == 200
    
    @pytest.mark.asyncio
    async def test_multi_module_operation_consistency(self, authenticated_client, test_data_manager):
        """测试多模块操作的事务一致性"""
        user_api = UserAPI(authenticated_client)
        role_api = RoleAPI(authenticated_client)
        notice_api = SysNoticeAPI(authenticated_client)
        
        unique_id = f"{int(time.time() * 1000)}"
        
        # 创建角色
        role_data = {
            "roleName": f"Multi_Role_{unique_id}",
            "roleKey": f"multi_role_{unique_id}",
            "roleSort": 1,
            "status": 1
        }
        role_response = await role_api.create_role(role_data)
        role_id = role_response.json()["id"]
        test_data_manager.add_role(role_id)
        
        # 创建用户
        user_data = {
            "username": f"multi_user_{unique_id}",
            "password": "Test123!@#",
            "email": f"multi_{unique_id}@example.com",
            "roleId": role_id,
            "status": 1
        }
        user_response = await user_api.create_user(user_data)
        user_id = user_response.json()["id"]
        test_data_manager.add_user(user_id)
        
        # 创建通知
        notice_data = {
            "noticeTitle": f"Multi_Notice_{unique_id}",
            "noticeType": "1",
            "noticeContent": f"用户 {user_data['username']} 已创建",
            "status": "0"
        }
        notice_response = await notice_api.create(notice_data)
        assert notice_response.status_code in [200, 201]
        
        # 验证所有操作都成功
        user_verify = await user_api.get_user_by_id(user_id)
        assert user_verify.status_code == 200
        
        role_verify = await role_api.get_role_by_id(role_id)
        assert role_verify.status_code == 200
        
        notices = await notice_api.get_all()
        assert notices.status_code == 200
        notice_list = notices.json()
        assert any(n["noticeTitle"] == notice_data["noticeTitle"] for n in notice_list)
    
    @pytest.mark.asyncio
    async def test_transaction_rollback_on_failure(self, authenticated_client, test_data_manager):
        """测试失败时的事务回滚"""
        user_api = UserAPI(authenticated_client)
        role_api = RoleAPI(authenticated_client)
        
        unique_id = f"{int(time.time() * 1000)}"
        
        # 创建角色
        role_data = {
            "roleName": f"Rollback_Role_{unique_id}",
            "roleKey": f"rollback_role_{unique_id}",
            "roleSort": 1,
            "status": 1
        }
        role_response = await role_api.create_role(role_data)
        role_id = role_response.json()["id"]
        test_data_manager.add_role(role_id)
        
        # 尝试创建无效用户（应该失败）
        invalid_user_data = {
            "username": "",  # 无效用户名
            "password": "Test123!@#",
            "email": f"rollback_{unique_id}@example.com",
            "roleId": role_id,
            "status": 1
        }
        
        invalid_response = await user_api.create_user(invalid_user_data)
        assert invalid_response.status_code in [400, 422]
        
        # 验证角色仍然存在（不应该被回滚）
        role_verify = await role_api.get_role_by_id(role_id)
        assert role_verify.status_code == 200