# -*- coding: utf-8 -*-
"""
集成测试
测试完整的业务流程和场景
所有测试在"测试目录 SIGN"文件夹内执行
"""
import pytest
import asyncio
import time
from typing import List, Tuple

from v123pan import V123Pan
from tests import config
from tests.utils import TestUtils


pytestmark = pytest.mark.integration


class TestFileLifecycle:
    """文件生命周期管理测试"""

    @pytest.mark.asyncio
    async def test_file_crud(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试文件创建、查询、更新、删除"""
        client, dir_id = authorized_client_with_dir

        # 创建文件（在测试目录内）
        filename = f"lifecycle_test_{int(time.time())}.txt"
        create_result = await client.file(
            dir_id,
            filename,
            "d41d8cd98f00b204e9800998ecf8427e",
            0
        )

        assert TestUtils.validate_response(create_result)
        file_id = create_result["data"]["fileID"]

        # 查询文件详情
        detail_result = await client.detail(file_id)
        assert TestUtils.validate_response(detail_result)
        assert detail_result["data"]["filename"] == filename

        # 重命名文件
        new_filename = f"renamed_{int(time.time())}.txt"
        rename_result = await client.name(file_id, new_filename)
        assert TestUtils.validate_response(rename_result)

        # 删除文件
        delete_result = await client.delete([file_id])
        assert TestUtils.validate_response(delete_result)

    @pytest.mark.asyncio
    async def test_file_copy_move(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试文件复制和移动"""
        client, dir_id = authorized_client_with_dir

        # 创建源文件（在测试目录内）
        filename = f"copy_move_test_{int(time.time())}.txt"
        create_result = await client.file(
            dir_id,
            filename,
            "d41d8cd98f00b204e9800998ecf8427e",
            0
        )
        file_id = create_result["data"]["fileID"]

        # 创建目标目录（在测试目录内）
        dir_name = f"dest_dir_{int(time.time())}"
        dir_result = await client.directory(dir_name, dir_id)
        target_dir_id = dir_result["data"]["dirID"]

        # 复制文件
        copy_result = await client.copy(file_id, target_dir_id)
        assert TestUtils.validate_response(copy_result)

        # 移动文件
        move_result = await client.move([file_id], dir_id)
        assert TestUtils.validate_response(move_result)

        # 清理
        await client.delete([file_id, target_dir_id])

    @pytest.mark.asyncio
    async def test_file_delete_recover(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试文件删除和恢复"""
        client, dir_id = authorized_client_with_dir

        # 创建文件
        filename = f"recover_test_{int(time.time())}.txt"
        create_result = await client.file(
            dir_id,
            filename,
            "d41d8cd98f00b204e9800998ecf8427e",
            0
        )
        file_id = create_result["data"]["fileID"]

        # 删除文件
        delete_result = await client.delete([file_id])
        assert TestUtils.validate_response(delete_result)

        # 恢复文件
        recover_result = await client.recover([file_id])
        assert TestUtils.validate_response(recover_result)

        # 再次删除
        delete_result2 = await client.delete([file_id])
        assert TestUtils.validate_response(delete_result2)


class TestDirectoryManagement:
    """目录管理测试"""

    @pytest.mark.asyncio
    async def test_directory_crud(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试目录创建、查询、删除"""
        client, dir_id = authorized_client_with_dir

        # 创建子目录（在测试目录内）
        dir_name = f"pytest_subdir_{int(time.time())}"
        create_result = await client.directory(dir_name, dir_id)

        assert TestUtils.validate_response(create_result)
        sub_dir_id = create_result["data"]["dirID"]

        # 查询目录列表
        list_result = await client.list(dir_id, 100)
        assert TestUtils.validate_response(list_result)

        # 删除目录
        delete_result = await client.delete([sub_dir_id])
        assert TestUtils.validate_response(delete_result)

    @pytest.mark.asyncio
    async def test_nested_directories(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试嵌套目录创建"""
        client, dir_id = authorized_client_with_dir

        # 创建父目录
        parent_name = f"parent_{int(time.time())}"
        parent_result = await client.directory(parent_name, dir_id)
        parent_id = parent_result["data"]["dirID"]

        # 创建子目录
        child_name = f"child_{int(time.time())}"
        child_result = await client.directory(child_name, parent_id)
        child_id = child_result["data"]["dirID"]

        # 创建孙目录
        grandchild_name = f"grandchild_{int(time.time())}"
        grandchild_result = await client.directory(grandchild_name, child_id)
        grandchild_id = grandchild_result["data"]["dirID"]

        # 验证层级关系
        list_result = await client.list(parent_id, 100)
        assert TestUtils.validate_response(list_result)

        # 清理
        await client.delete([grandchild_id, child_id, parent_id])


class TestFileQuery:
    """文件查询测试"""

    @pytest.mark.asyncio
    async def test_file_list_pagination(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试文件列表分页"""
        client, dir_id = authorized_client_with_dir

        # 创建多个文件
        file_ids: List[int] = []
        for i in range(5):
            filename = f"page_test_{i}_{int(time.time())}.txt"
            result = await client.file(
                dir_id,
                filename,
                "d41d8cd98f00b204e9800998ecf8427e",
                0
            )
            if TestUtils.validate_response(result):
                file_ids.append(result["data"]["fileID"])

        # 分页查询
        page_result = await client.page(dir_id, 1, 10, "file_name", "asc")
        assert TestUtils.validate_response(page_result)

        # 清理
        if file_ids:
            await client.delete(file_ids)

    @pytest.mark.asyncio
    async def test_file_search(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试文件搜索"""
        client, dir_id = authorized_client_with_dir

        # 创建测试文件
        unique_name = f"search_test_{int(time.time())}.txt"
        create_result = await client.file(
            dir_id,
            unique_name,
            "d41d8cd98f00b204e9800998ecf8427e",
            0
        )
        file_id = create_result["data"]["fileID"]

        # 搜索文件
        search_result = await client.list(
            dir_id,
            100,
            search_data="search_test",
            search_mode=0
        )
        assert TestUtils.validate_response(search_result)

        # 清理
        await client.delete([file_id])


class TestBatchOperations:
    """批量操作测试"""

    @pytest.mark.asyncio
    async def test_batch_delete(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试批量删除"""
        client, dir_id = authorized_client_with_dir

        # 创建多个文件
        file_ids: List[int] = []
        for i in range(3):
            filename = f"batch_del_{i}_{int(time.time())}.txt"
            result = await client.file(
                dir_id,
                filename,
                "d41d8cd98f00b204e9800998ecf8427e",
                0
            )
            if TestUtils.validate_response(result):
                file_ids.append(result["data"]["fileID"])

        # 批量删除
        delete_result = await client.delete(file_ids)
        assert TestUtils.validate_response(delete_result)

    @pytest.mark.asyncio
    async def test_batch_rename(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试批量重命名"""
        client, dir_id = authorized_client_with_dir

        # 创建多个文件
        file_ids: List[int] = []
        for i in range(3):
            filename = f"batch_rename_{i}_{int(time.time())}.txt"
            result = await client.file(
                dir_id,
                filename,
                "d41d8cd98f00b204e9800998ecf8427e",
                0
            )
            if TestUtils.validate_response(result):
                file_ids.append(result["data"]["fileID"])

        # 批量重命名
        rename_list = [f"{fid}|new_name_{i}.txt" for i, fid in enumerate(file_ids)]
        rename_result = await client.rename_batch(rename_list)
        assert TestUtils.validate_response(rename_result)

        # 清理
        await client.delete(file_ids)


class TestUpload:
    """上传测试"""

    @pytest.mark.asyncio
    async def test_file_quick_transfer(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试文件秒传"""
        client, dir_id = authorized_client_with_dir

        filename = f"quick_transfer_{int(time.time())}.txt"
        result = await client.file(
            dir_id,
            filename,
            "d41d8cd98f00b204e9800998ecf8427e",
            0
        )

        assert TestUtils.validate_response(result)
        file_id = result["data"]["fileID"]
        assert file_id > 0

        # 清理
        await client.delete([file_id])

    @pytest.mark.asyncio
    async def test_sha1_quick_transfer(self, authorized_client_with_dir: Tuple[V123Pan, int]):
        """测试 SHA1 秒传"""
        client, dir_id = authorized_client_with_dir

        filename = f"sha1_transfer_{int(time.time())}.txt"
        result = await client.reuse(
            dir_id,
            filename,
            "da39a3ee5e6b4b0d3255bfef95601890afd80709",
            0
        )

        assert TestUtils.validate_response(result)
        assert TestUtils.validate_field(result, "data.reuse", bool, True)

        file_id = result["data"]["fileID"]
        assert file_id > 0

        # 清理
        await client.delete([file_id])
