"""
Azure Data Factory module.

Provides flexible interfaces to Azure Data Factory with support for
module-level singleton, multi-client, and context manager patterns.

Usage:
    # Module-level singleton (most common)
    >>> from fabias.integrations import adf
    >>> adf.client(
    ...     subscription_id="...",
    ...     resource_group="rg-data",
    ...     factory="adf-prod",
    ...     auth=my_auth
    ... )
    >>>
    >>> # Run a pipeline
    >>> job = adf.pipeline("Daily_ETL").run()
    >>> job.wait()
    >>>
    >>> # List pipelines
    >>> for pipeline in adf.pipelines():
    ...     print(f"{pipeline.name}: {len(pipeline.activities)} activities")

    # Multi-client usage
    >>> adf_prod = adf.client(factory="adf-prod", auth=auth1, ...)
    >>> adf_dev = adf.client(factory="adf-dev", auth=auth2, ...)
    >>> prod_pipelines = adf_prod.pipelines()
    >>> dev_pipelines = adf_dev.pipelines()

    # Context manager
    >>> with adf.client(factory="...", auth=my_auth, ...) as client:
    ...     pipelines = client.pipelines()
"""

from typing import List, Optional

from ..._shared.auth import AuthProvider
from ..._shared.exceptions import FabiasError
from .client import DataFactoryClient
from .pipeline import Pipeline

# Module-level singleton
_client: Optional[DataFactoryClient] = None
_configured: bool = False


def client(
    subscription_id: str,
    resource_group: str,
    factory: str,
    auth: Optional[AuthProvider] = None,
    tenant_id: Optional[str] = None,
    client_id: Optional[str] = None,
    client_secret: Optional[str] = None,
) -> DataFactoryClient:
    """
    Create or configure the Data Factory client.

    When called as a module-level function, sets up the singleton for convenience.
    Returns the client instance for both module-level and explicit multi-client use.

    Args:
        subscription_id: Azure subscription ID
        resource_group: Resource group containing the factory
        factory: Data Factory name
        auth: Pre-configured AuthProvider (recommended)
        tenant_id: Azure AD tenant ID (alternative to auth)
        client_id: Application (client) ID (alternative to auth)
        client_secret: Client secret value (alternative to auth)

    Returns:
        DataFactoryClient: Configured client instance

    Examples:
        # Module-level singleton (most common)
        >>> import fabias.datafactory as adf
        >>> adf.client(
        ...     subscription_id="your-sub",
        ...     resource_group="rg-data",
        ...     factory="adf-prod",
        ...     auth=my_auth
        ... )
        >>> pipelines = adf.pipelines()

        # Multi-client usage
        >>> adf_prod = adf.client(factory="adf-prod", auth=auth1, ...)
        >>> adf_dev = adf.client(factory="adf-dev", auth=auth2, ...)
        >>> prod_pipelines = adf_prod.pipelines()

        # Context manager
        >>> with adf.client(factory="...", auth=my_auth, ...) as client:
        ...     pipelines = client.pipelines()
    """
    global _client, _configured

    new_client = DataFactoryClient(
        subscription_id=subscription_id,
        resource_group=resource_group,
        factory=factory,
        auth=auth,
        tenant_id=tenant_id,
        client_id=client_id,
        client_secret=client_secret,
    )

    # Set as module singleton
    _client = new_client
    _configured = True

    return new_client


def _get_client() -> DataFactoryClient:
    """Get the configured client or raise an error."""
    if _client is None:
        raise FabiasError(
            "Data Factory module not configured. " "Call datafactory.client(...) first."
        )
    return _client


def reset() -> None:
    """Reset module state, clearing the cached client."""
    global _client, _configured
    _client = None
    _configured = False


# =============================================================================
# Module-level API
# =============================================================================


def pipeline(name: str) -> Pipeline:
    """
    Get a pipeline by name.

    Args:
        name: Pipeline name

    Returns:
        Pipeline: Pipeline object for execution

    Examples:
        >>> job = adf.pipeline("Daily_ETL").run()
        >>> job.wait()
    """
    return _get_client().pipeline(name)


def pipelines() -> List[Pipeline]:
    """
    List all pipelines in the factory.

    Returns Pipeline objects pre-populated with metadata, so no additional
    API calls are needed to access their properties.

    Returns:
        List[Pipeline]: List of Pipeline objects

    Examples:
        >>> for pipeline in adf.pipelines():
        ...     print(f"{pipeline.name}: {len(pipeline.activities)} activities")
    """
    return _get_client().pipelines()


__all__ = [
    "client",
    "reset",
    "pipeline",
    "pipelines",
    "DataFactoryClient",
    "Pipeline",
]
