"""
Asset handling utilities for packaging operations.

Provides utilities for discovering, processing, and managing
assets within packages.
"""

import hashlib
import mimetypes
from pathlib import Path
from typing import List, Set, Dict, Optional

from .metadata import AssetMetadata
from .errors import AssetError


class AssetUtils:
    """Utilities for asset handling in packages."""

    @staticmethod
    def discover_assets(source_path: Path,
                       asset_extensions: Optional[Set[str]] = None) -> List[Path]:
        """
        Discover assets in a source directory.

        Args:
            source_path: Path to search for assets
            asset_extensions: Set of file extensions to consider as assets
                            If None, uses default set

        Returns:
            List of asset file paths
        """
        if asset_extensions is None:
            asset_extensions = {
                '.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp',  # Images
                '.pdf', '.doc', '.docx', '.txt',  # Documents
                '.mp3', '.wav', '.ogg',  # Audio
                '.mp4', '.webm', '.avi',  # Video
                '.css', '.js',  # Web assets
                '.json', '.yaml', '.yml'  # Data files
            }

        assets = []
        if source_path.is_file():
            # Single file source
            if source_path.suffix.lower() in asset_extensions:
                assets.append(source_path)
        else:
            # Directory source
            for file_path in source_path.rglob('*'):
                if (file_path.is_file() and
                    file_path.suffix.lower() in asset_extensions):
                    assets.append(file_path)

        return assets

    @staticmethod
    def create_asset_metadata(file_path: Path,
                            package_path: str,
                            original_path: str = None) -> AssetMetadata:
        """
        Create metadata for an asset file.

        Args:
            file_path: Path to the asset file
            package_path: Path within the package
            original_path: Original path before processing

        Returns:
            AssetMetadata object
        """
        if not file_path.exists():
            raise AssetError(f"Asset file not found: {file_path}")

        # Calculate file size
        size = file_path.stat().st_size

        # Calculate checksum
        checksum = AssetUtils.calculate_checksum(file_path)

        # Determine MIME type
        mime_type, _ = mimetypes.guess_type(str(file_path))

        return AssetMetadata(
            path=package_path,
            original_path=original_path or str(file_path),
            size=size,
            checksum=checksum,
            mime_type=mime_type
        )

    @staticmethod
    def calculate_checksum(file_path: Path) -> str:
        """
        Calculate SHA-256 checksum of a file.

        Args:
            file_path: Path to the file

        Returns:
            Hexadecimal checksum string
        """
        sha256_hash = hashlib.sha256()
        try:
            with open(file_path, "rb") as f:
                for chunk in iter(lambda: f.read(4096), b""):
                    sha256_hash.update(chunk)
        except IOError as e:
            raise AssetError(f"Failed to read file for checksum: {e}")

        return sha256_hash.hexdigest()

    @staticmethod
    def validate_asset_integrity(file_path: Path, expected_checksum: str) -> bool:
        """
        Validate asset integrity using checksum.

        Args:
            file_path: Path to the asset file
            expected_checksum: Expected checksum

        Returns:
            True if checksums match, False otherwise
        """
        try:
            actual_checksum = AssetUtils.calculate_checksum(file_path)
            return actual_checksum == expected_checksum
        except AssetError:
            return False


# Standalone utility functions for convenience
def discover_assets(source_path: Path, asset_extensions: Optional[Set[str]] = None) -> List[Path]:
    """
    Standalone wrapper for AssetUtils.discover_assets.

    Args:
        source_path: Path to search for assets
        asset_extensions: Set of file extensions to consider as assets

    Returns:
        List of asset file paths
    """
    return AssetUtils.discover_assets(source_path, asset_extensions)


def resolve_asset_path(base_path: Path, asset_path: str) -> Path:
    """
    Resolve asset path relative to base path.

    Args:
        base_path: Base directory path
        asset_path: Asset path (relative or absolute)

    Returns:
        Resolved asset path
    """
    if Path(asset_path).is_absolute():
        return Path(asset_path)
    return base_path / asset_path


def detect_mime_type(file_path: Path) -> Optional[str]:
    """
    Detect MIME type of a file.

    Args:
        file_path: Path to the file

    Returns:
        MIME type string or None
    """
    mime_type, _ = mimetypes.guess_type(str(file_path))
    return mime_type