# -*- coding: utf-8 -*-
"""
常量和配置模块
定义 API 路径、常量等
"""

import asyncio
from dataclasses import dataclass, field
from typing import Final
from urllib.parse import urljoin

BASE_URL: Final[str] = "https://open-api.123pan.com"
PLATFORM: Final[str] = "open_platform"
CONTENT_TYPE: Final[str] = "application/json"


@dataclass
class Api:
    """
    API 配置类

    Attributes:
        method: HTTP 方法（GET, POST, PUT, DELETE）
        url: API URL
        qps: QPS 限制，默认 100
        semaphore: 并发控制信号量
    """

    method: str
    url: str
    qps: int = 100
    semaphore: asyncio.Semaphore = field(default=None)

    def __post_init__(self) -> None:
        """初始化后处理，创建信号量"""
        if self.semaphore is None:
            self.semaphore = asyncio.Semaphore(self.qps if self.qps > 0 else 100)


@dataclass(frozen=True, slots=True)
class ApiPaths:
    """API 路径配置类"""

    access_token: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "api/v1/access_token"), 10))
    mkdir: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "upload/v1/file/mkdir"), 20))
    create_file: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "upload/v1/file/create")))
    get_upload_url: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "upload/v1/file/get_upload_url")))
    list_upload_parts: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "upload/v1/file/list_upload_parts")))
    upload_complete: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "upload/v1/file/upload_complete")))
    upload_async_result: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "upload/v1/file/upload_async_result")))
    sha1_reuse: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "upload/v2/file/sha1_reuse")))
    rename_file: Api = field(default_factory=lambda: Api("PUT", urljoin(BASE_URL, "api/v1/file/name")))
    batch_rename: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "api/v1/file/rename")))
    trash: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "api/v1/file/trash")))
    copy: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "api/v1/file/copy")))
    async_copy: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "api/v1/file/async/copy")))
    async_copy_process: Api = field(default_factory=lambda: Api("GET", urljoin(BASE_URL, "api/v1/file/async/copy/process")))
    recover: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "api/v1/file/recover")))
    recover_by_path: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "api/v1/file/recover/by_path")))
    file_detail: Api = field(default_factory=lambda: Api("GET", urljoin(BASE_URL, "api/v1/file/detail")))
    file_infos: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "api/v1/file/infos")))
    file_list_v2: Api = field(default_factory=lambda: Api("GET", urljoin(BASE_URL, "api/v2/file/list"), 15))
    file_list: Api = field(default_factory=lambda: Api("GET", urljoin(BASE_URL, "api/v1/file/list"), 10))
    move: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "api/v1/file/move")))
    get_download_url: Api = field(default_factory=lambda: Api("GET", urljoin(BASE_URL, "api/v1/file/download_info"), 5))
    offline_download: Api = field(default_factory=lambda: Api("POST", urljoin(BASE_URL, "api/v1/offline/download")))
    offline_download_process: Api = field(default_factory=lambda: Api("GET", urljoin(BASE_URL, "api/v1/offline/download/process")))
    user_info: Api = field(default_factory=lambda: Api("GET", urljoin(BASE_URL, "api/v1/user/info")))


@dataclass(frozen=True, slots=True)
class FileType:
    """文件类型常量"""

    FILE: int = 0
    FOLDER: int = 1


@dataclass(frozen=True, slots=True)
class FileCategory:
    """文件分类常量"""

    UNKNOWN: int = 0
    AUDIO: int = 1
    VIDEO: int = 2
    IMAGE: int = 3


@dataclass(frozen=True, slots=True)
class TaskStatus:
    """任务状态常量"""

    PENDING: int = 0
    IN_PROGRESS: int = 1
    COMPLETED: int = 2
    FAILED: int = 3


@dataclass(frozen=True, slots=True)
class DownloadStatus:
    """下载状态常量"""

    IN_PROGRESS: int = 0
    FAILED: int = 1
    SUCCESS: int = 2
    RETRYING: int = 3


@dataclass(frozen=True, slots=True)
class BatchLimits:
    """批量操作限制常量"""

    MOVE_BATCH_SIZE: int = 100          # 移动文件最大批量数
    DELETE_BATCH_SIZE: int = 100         # 删除文件最大批量数
    RENAME_BATCH_SIZE: int = 30          # 重命名文件最大批量数
    COPY_ASYNC_BATCH_SIZE: int = 3000    # 异步复制单批最大文件数
    FILE_INFO_BATCH_SIZE: int = 100      # 文件信息批量获取最大数量


API_PATHS: ApiPaths = ApiPaths()
FILE_TYPE: FileType = FileType()
FILE_CATEGORY: FileCategory = FileCategory()
TASK_STATUS: TaskStatus = TaskStatus()
DOWNLOAD_STATUS: DownloadStatus = DownloadStatus()
BATCH_LIMITS: BatchLimits = BatchLimits()
