from __future__ import annotations

from dataclasses import dataclass, field
from pathlib import Path
from typing import Literal

from .download_task import DownloadTask


@dataclass(slots=True)
class RetryPolicy:
    max_attempts: int = 3
    backoff_seconds: float = 0.5
    max_backoff_seconds: float = 4.0


@dataclass(slots=True)
class DownloadConfig:
    workers: int = 4
    chunk_size: int = 1024 * 256
    timeout_seconds: float = 30.0
    retry_policy: RetryPolicy = field(default_factory=RetryPolicy)
    mem_assemble: bool = True


@dataclass(slots=True)
class DownloadProgress:
    downloaded_bytes: int
    total_bytes: int | None
    worker_count: int
    mode: Literal["single", "multi"]

    @property
    def percent(self) -> float | None:
        if not self.total_bytes or self.total_bytes <= 0:
            return None
        return min((self.downloaded_bytes / self.total_bytes) * 100.0, 100.0)


@dataclass(slots=True)
class DownloadResult:
    url: str
    output_path: Path
    bytes_written: int
    used_multi_thread: bool
    range_supported: bool


__all__ = [
    "DownloadTask",
    "RetryPolicy",
    "DownloadConfig",
    "DownloadProgress",
    "DownloadResult",
]
