"""
Config downloader for worker.

Single Responsibility: Download job configs from S3 to local temp directory.
"""

import tempfile
from pathlib import Path

from ..clients.s3_client import S3Client


class ConfigDownloader:
    """
    Download job configs from S3.

    Handles both single files and directory structures.
    """

    def __init__(self, s3_client: S3Client):
        """
        Initialize config downloader.

        Args:
            s3_client: S3 client for downloads
        """
        self.s3_client = s3_client

    def download_config(
        self, config_s3_path: str, config_type: str = "file"
    ) -> Path:
        """
        Download config from S3 to temp directory.

        Args:
            config_s3_path: S3 path (s3://bucket/key or just key)
            config_type: 'file' or 'directory'

        Returns:
            Local path to downloaded config (file or directory)

        Raises:
            RuntimeError: If download fails
        """
        # Extract S3 key from path
        s3_key = self._extract_s3_key(config_s3_path)

        if config_type == "file":
            return self._download_single_file(s3_key)
        elif config_type == "directory":
            return self._download_directory(s3_key)
        else:
            raise ValueError(f"Invalid config_type: {config_type}")

    def _extract_s3_key(self, s3_path: str) -> str:
        """
        Extract S3 key from full path.

        Args:
            s3_path: S3 URI (s3://bucket/key) or just key

        Returns:
            S3 key (without bucket)
        """
        if s3_path.startswith("s3://"):
            # Extract key from s3://bucket/key
            parts = s3_path.replace("s3://", "").split("/", 1)
            if len(parts) > 1:
                return parts[1]
            return parts[0]
        return s3_path

    def _download_single_file(self, s3_key: str) -> Path:
        """
        Download single config file.

        Args:
            s3_key: S3 object key

        Returns:
            Local path to downloaded file
        """
        # Create temp file
        temp_dir = Path(tempfile.mkdtemp(prefix="czbg_config_"))
        local_path = temp_dir / "config.yaml"

        # Download from S3
        self.s3_client.download_file(s3_key, local_path)

        return local_path

    def _download_directory(self, s3_prefix: str) -> Path:
        """
        Download config directory structure.

        Args:
            s3_prefix: S3 prefix for directory

        Returns:
            Local path to directory root
        """
        # Create temp directory
        temp_dir = Path(tempfile.mkdtemp(prefix="czbg_config_"))
        configs_dir = temp_dir / "configs"
        configs_dir.mkdir()

        # List all objects under prefix
        s3_keys = self.s3_client.list_objects(s3_prefix)

        # Download each file preserving structure
        for s3_key in s3_keys:
            # Skip directory markers (keys ending with /)
            if s3_key.endswith("/"):
                continue

            # Extract relative path from prefix
            relative_path = s3_key.replace(s3_prefix, "").lstrip("/")
            local_file = configs_dir / relative_path

            # Create parent directory if needed
            local_file.parent.mkdir(parents=True, exist_ok=True)

            # Download file
            self.s3_client.download_file(s3_key, local_file)

        return configs_dir
