"""
Registry factory for creating registry clients.

This module provides a factory for creating appropriate registry clients
based on configuration or registry type.
"""

from typing import Dict, Type, Optional, Any
from pathlib import Path

from .base import RegistryInterface, RegistryConfig
from .gitea.registry import GiteaRegistry
from .gitea.config import GiteaConfig


class RegistryFactory:
    """Factory for creating registry clients."""

    _registry_types: Dict[str, Type[RegistryInterface]] = {
        'gitea': GiteaRegistry,
    }

    @classmethod
    def create(cls, registry_type: str, config: Optional[Dict[str, Any]] = None) -> RegistryInterface:
        """Create a registry client of the specified type.

        Args:
            registry_type: Type of registry ('gitea', 'pypi', etc.)
            config: Optional configuration dictionary

        Returns:
            Registry client instance

        Raises:
            ValueError: If registry type is not supported
        """
        if registry_type not in cls._registry_types:
            raise ValueError(f"Unsupported registry type: {registry_type}. "
                           f"Supported types: {list(cls._registry_types.keys())}")

        registry_class = cls._registry_types[registry_type]

        # Handle Gitea-specific configuration
        if registry_type == 'gitea':
            if config:
                gitea_config = GiteaConfig(
                    gitea_url=config.get('url', ''),
                    repo_owner=config.get('owner', ''),
                    repo_name=config.get('repo', ''),
                    auth_token=config.get('auth_token')
                )
                return registry_class(gitea_config)
            else:
                # Auto-detect from git repository
                return registry_class()

        # For other registry types, create with generic config
        if config:
            registry_config = RegistryConfig(
                name=config.get('name', registry_type),
                type=registry_type,
                url=config['url'],
                auth_token_env=config.get('auth_token_env')
            )
            return registry_class(registry_config)
        else:
            raise ValueError(f"Configuration required for {registry_type} registry")

    @classmethod
    def create_from_pyproject_config(cls, pyproject_path: Optional[Path] = None,
                                   registry_name: str = 'gitea') -> RegistryInterface:
        """Create a registry client from pyproject.toml configuration.

        Args:
            pyproject_path: Path to pyproject.toml file. If None, looks in current directory.
            registry_name: Name of registry configuration to use

        Returns:
            Registry client instance

        Raises:
            ValueError: If configuration is invalid or registry not found
        """
        if pyproject_path is None:
            pyproject_path = Path.cwd() / "pyproject.toml"

        if not pyproject_path.exists():
            raise ValueError(f"pyproject.toml not found at {pyproject_path}")

        try:
            import tomllib
        except ImportError:
            try:
                import tomli as tomllib  # Fallback for Python < 3.11
            except ImportError:
                raise ImportError("tomllib or tomli required to read pyproject.toml")

        with open(pyproject_path, 'rb') as f:
            config = tomllib.load(f)

        # Look for release-management configuration
        release_config = config.get('tool', {}).get('release-management', {})
        registries_config = release_config.get('registries', {})

        if registry_name not in registries_config:
            raise ValueError(f"Registry '{registry_name}' not found in pyproject.toml configuration")

        registry_config = registries_config[registry_name]
        registry_type = registry_config.get('type', registry_name)

        # Add auth token from environment if specified
        auth_token_env = registry_config.get('auth_token_env')
        if auth_token_env:
            import os
            registry_config = registry_config.copy()
            registry_config['auth_token'] = os.getenv(auth_token_env)

        return cls.create(registry_type, registry_config)

    @classmethod
    def auto_detect(cls) -> RegistryInterface:
        """Auto-detect registry type from current environment.

        Currently only supports Gitea auto-detection from git repository.

        Returns:
            Registry client instance

        Raises:
            ValueError: If no registry can be auto-detected
        """
        # Try Gitea auto-detection first
        try:
            return cls.create('gitea')
        except Exception:
            pass

        raise ValueError("Could not auto-detect registry type. "
                        "Ensure you're in a git repository with Gitea remote, "
                        "or provide explicit configuration.")

    @classmethod
    def register_registry_type(cls, registry_type: str, registry_class: Type[RegistryInterface]) -> None:
        """Register a new registry type.

        Args:
            registry_type: String identifier for the registry type
            registry_class: Registry class that implements RegistryInterface
        """
        cls._registry_types[registry_type] = registry_class

    @classmethod
    def list_supported_types(cls) -> list[str]:
        """List all supported registry types.

        Returns:
            List of supported registry type strings
        """
        return list(cls._registry_types.keys())