"""Shared data types for vcm-file-uploader."""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime, timezone


@dataclass(frozen=True)
class TransferConfig:
    """Configuration for boto3 S3 TransferManager."""

    multipart_threshold: int = 128 * 1024 * 1024  # 128 MiB
    multipart_chunksize: int = 128 * 1024 * 1024  # 128 MiB
    max_concurrency: int = 8


@dataclass(frozen=True)
class UploadFileEntry:
    """A single file entry from an upload plan."""

    path: str
    full_path: str
    size: int
    category: str | None = None
    sha256: str | None = None
    reason: str = "unknown"
    multipart: bool = False


@dataclass(frozen=True)
class CompressionInfo:
    """Compression metadata for a compressed upload."""

    algorithm: str = "gzip"
    level: int = 6
    original_bytes: int = 0
    compressed_bytes: int = 0


@dataclass
class UploadResult:
    """Result of a single file upload."""

    local_path: str
    s3_key: str
    size: int
    success: bool
    error: str | None = None
    compression: CompressionInfo | None = None
    uploaded_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))


@dataclass
class UploadSummary:
    """Summary of an upload_files() run."""

    results: list[UploadResult] = field(default_factory=list)

    @property
    def succeeded(self) -> list[UploadResult]:
        return [r for r in self.results if r.success]

    @property
    def failed(self) -> list[UploadResult]:
        return [r for r in self.results if not r.success]

    @property
    def total_bytes(self) -> int:
        return sum(r.size for r in self.succeeded)

    @property
    def all_succeeded(self) -> bool:
        return len(self.failed) == 0 and len(self.results) > 0

    @property
    def exit_code(self) -> int:
        """Return an exit code for programmatic callers.

        0 = all uploads succeeded
        1 = partial failure (some succeeded, some failed)
        2 = total failure (all uploads failed or no uploads attempted)
        """
        if self.all_succeeded:
            return 0
        if self.succeeded:
            return 1
        return 2
