"""BZ2 compression of .bsp map files for FastDL distribution."""

import bz2
import shutil
from pathlib import Path

from core.exceptions import CompressionError

# ==========================================================================
# 1. COUCHE DE VALIDATION (Responsabilité : Intégrité avant compression)
# ==========================================================================


def _validate_compress_inputs(source_file: Path) -> None:
    """Ensures that the source file is valid and eligible for compression."""
    if not source_file.exists():
        msg = f"File not found : {source_file}"
        raise FileNotFoundError(msg)

    if source_file.suffix.lower() != ".bsp":
        msg_0 = f"The file must be a .bsp file : {source_file}"
        raise CompressionError(msg_0)


# ==========================================================================
# 2. LOGIQUE PURE DE COMPRESSION (Responsabilité : Transformation binaire)
# ==========================================================================


def compress_bsp(source_file: str | Path, destination_file: str | Path | None = None) -> Path:
    """Compresses a BSP file into bz2 format (Level 1 optimization for speed)."""
    source_path = Path(source_file)

    _validate_compress_inputs(source_path)

    target_path = (
        Path(destination_file) if destination_file is not None else Path(f"{source_path}.bz2")
    )

    with (
        source_path.open("rb") as source,
        bz2.open(target_path, "wb", compresslevel=1) as destination,
    ):
        shutil.copyfileobj(source, destination)

    return target_path


def compress_to_download_folder(bsp_file: str | Path, download_folder: str | Path) -> Path:
    """Ensures that the target FastDL folder is created and compresses the BSP file into it."""
    bsp_file = Path(bsp_file)
    download_folder = Path(download_folder)

    download_folder.mkdir(parents=True, exist_ok=True)

    destination = download_folder / f"{bsp_file.name}.bz2"
    return compress_bsp(bsp_file, destination)
