"""
S3 config uploader for API job submission.

Uploads config files to S3 before job submission.
Follows CLAUDE.md: Single responsibility, <10 methods, <50 lines/method.
"""

import boto3
import os
from pathlib import Path


class S3ConfigUploader:
    """
    Upload config files to S3.

    Single responsibility: S3 config upload.
    """

    def __init__(self):
        """Initialize S3 uploader."""
        # Create session with profile if available
        session = boto3.Session()
        if os.getenv("AWS_PROFILE"):
            session = boto3.Session(profile_name=os.getenv("AWS_PROFILE"))

        self.s3_client = session.client("s3")
        self.bucket_name = os.getenv(
            "S3_BUCKET_NAME", "cz-demo-tools-custom-billing-data-3892j3292sasdf"
        )

    def upload_config(self, config_path: Path, job_type: str, job_id: str) -> str:
        """
        Upload config to S3 with job_type and job_id in path.

        Args:
            config_path: Path to config file or directory
            job_type: Job type for S3 key organization (generate, k8s, etc.)
            job_id: Job ID for S3 key (enables direct path reconstruction)

        Returns:
            S3 key (not full S3 URI)

        Raises:
            FileNotFoundError: If config path doesn't exist
            RuntimeError: If upload fails
        """
        if not config_path.exists():
            raise FileNotFoundError(f"Config path not found: {config_path}")

        # Use job_type/job_id for organized S3 structure
        base_key = f"czbillgen/api-jobs/{job_type}/{job_id}"

        if config_path.is_file():
            # Upload single file
            s3_key = f"{base_key}/{config_path.name}"
            self._upload_file(config_path, s3_key)
            return s3_key  # Return just the key, not full S3 URI
        else:
            # Upload directory
            self._upload_directory(config_path, base_key)
            return f"{base_key}/"  # Return just the key, not full S3 URI

    def _upload_file(self, file_path: Path, s3_key: str) -> None:
        """Upload single file to S3."""
        self.s3_client.upload_file(str(file_path), self.bucket_name, s3_key)

    def _upload_directory(self, dir_path: Path, base_key: str) -> None:
        """
        Upload directory to S3.

        Args:
            dir_path: Directory to upload
            base_key: Base S3 key prefix
        """
        for file_path in dir_path.rglob("*.yaml"):
            relative_path = file_path.relative_to(dir_path)
            s3_key = f"{base_key}/{relative_path}"
            self._upload_file(file_path, s3_key)

        for file_path in dir_path.rglob("*.yml"):
            relative_path = file_path.relative_to(dir_path)
            s3_key = f"{base_key}/{relative_path}"
            self._upload_file(file_path, s3_key)
