"""
Azure Data Factory REST API client.
"""

from typing import List, Optional

from ..._shared.auth import AuthProvider, ServicePrincipalAuth
from ..._shared.client import BaseClient
from ..._shared.exceptions import FabiasError
from .pipeline import Pipeline


class DataFactoryClient(BaseClient):
    """
    HTTP client for Azure Data Factory REST API.

    Configured for a specific factory within a subscription/resource group.
    """

    MANAGEMENT_SCOPE = "https://management.azure.com/.default"
    MANAGEMENT_API_URL = "https://management.azure.com"
    API_VERSION = "2018-06-01"

    def __init__(
        self,
        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,
    ):
        """
        Initialize the Data Factory client.

        Args:
            subscription_id: Azure subscription ID
            resource_group: Resource group name
            factory: Data Factory name
            auth: Optional pre-configured AuthProvider
            tenant_id: Azure AD tenant ID
            client_id: Application client ID
            client_secret: Client secret
        """
        # Determine authentication method
        if auth:
            auth_provider = auth
        elif tenant_id and client_id and client_secret:
            auth_provider = ServicePrincipalAuth(
                tenant_id=tenant_id, client_id=client_id, client_secret=client_secret
            )
        else:
            raise FabiasError(
                "Azure Data Factory requires explicit credentials. "
                "Provide either 'auth' or all of 'tenant_id', 'client_id', and 'client_secret'."
            )

        super().__init__(auth_provider)

        self._subscription_id = subscription_id
        self._resource_group = resource_group
        self._factory = factory
        self._scope = self.MANAGEMENT_SCOPE

        # Base URI points directly to the factory
        self._base_uri = (
            f"{self.MANAGEMENT_API_URL}"
            f"/subscriptions/{subscription_id}"
            f"/resourceGroups/{resource_group}"
            f"/providers/Microsoft.DataFactory"
            f"/factories/{factory}"
        )

    @property
    def factory(self) -> str:
        """Get the configured factory name."""
        return self._factory

    @property
    def resourceGroup(self) -> str:
        """Get the configured resource group."""
        return self._resource_group

    @property
    def subscriptionId(self) -> str:
        """Get the configured subscription ID."""
        return self._subscription_id

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

        Args:
            name: Pipeline name

        Returns:
            Pipeline: Pipeline object for execution
        """
        return Pipeline(self, name)

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

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

        Returns:
            List[Pipeline]: List of Pipeline objects with cached metadata

        Examples:
            >>> for pipeline in adf.pipelines():
            ...     print(f"{pipeline.name}: {len(pipeline.activities)} activities")
        """
        response = self.get(f"/pipelines?api-version={self.API_VERSION}")
        pipeline_data_list = response.json().get("value", [])

        # Create Pipeline objects pre-populated with data
        return [Pipeline(self, data["name"], data=data) for data in pipeline_data_list]

    def __enter__(self):
        """Context manager entry."""
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """Context manager exit - cleanup if needed."""
        # Add any cleanup logic here if needed in the future
        pass
