"""
Utility to read Azure environment variables and provide authenticated Azure SDK clients.

Usage:
- Set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID for a service principal.
- Or rely on DefaultAzureCredential (Managed Identity, Azure CLI, etc.).
- AZURE_SUBSCRIPTION_ID is required for subscription-scoped clients.

The module avoids hard dependency on azure packages at import time; it performs lazy imports and provides informative errors
if the package isn't installed.
"""
from __future__ import annotations

import os
from typing import Optional


def _get_env(key: str, required: bool = True) -> Optional[str]:
    val = os.getenv(key)
    if required and not val:
        raise RuntimeError(f"Missing required environment variable: {key}")
    return val


def get_subscription_id() -> str:
    """Return AZURE_SUBSCRIPTION_ID or raise RuntimeError if unset."""
    return _get_env("AZURE_SUBSCRIPTION_ID")


def get_credential():
    """
    Return an Azure credential instance.

    Priority:
    - If AZURE_CLIENT_ID, AZURE_CLIENT_SECRET and AZURE_TENANT_ID are set, return ClientSecretCredential.
    - Otherwise return DefaultAzureCredential.

    Raises RuntimeError if required packages are missing.
    """
    client_id = os.getenv("AZURE_CLIENT_ID")
    client_secret = os.getenv("AZURE_CLIENT_SECRET")
    tenant_id = os.getenv("AZURE_TENANT_ID")

    if client_id and client_secret and tenant_id:
        try:
            from azure.identity import ClientSecretCredential  # type: ignore[import]
        except Exception as exc:  # ImportError or similar
            raise RuntimeError(
                "azure-identity is required to use ClientSecretCredential. Install with 'pip install azure-identity'."
            ) from exc

        return ClientSecretCredential(
            tenant_id=tenant_id, client_id=client_id, client_secret=client_secret
        )

    # fallback
    try:
        from azure.identity import DefaultAzureCredential  # type: ignore[import]
    except Exception as exc:
        raise RuntimeError(
            "azure-identity is required for DefaultAzureCredential. Install with 'pip install azure-identity'."
        ) from exc

    return DefaultAzureCredential()


def create_resource_client(credential=None, subscription_id: Optional[str] = None):
    """
    Create and return an instance of azure.mgmt.resource.ResourceManagementClient.

    If credential or subscription_id are not provided, they will be read using helpers above.
    """
    if credential is None:
        credential = get_credential()
    if subscription_id is None:
        subscription_id = get_subscription_id()

    try:
        from azure.mgmt.resource import ResourceManagementClient  # type: ignore[import]
    except Exception as exc:
        raise RuntimeError(
            "azure-mgmt-resource is required to create ResourceManagementClient. Install with 'pip install azure-mgmt-resource'."
        ) from exc

    return ResourceManagementClient(credential, subscription_id)


def create_policyinsights_client(
    credential=None, subscription_id: Optional[str] = None
):
    """
    Create and return an instance of azure.mgmt.policyinsights.PolicyInsightsClient.

    Some policy clients are not subscription-scoped and may not require subscription_id but accepting it keeps API parity.
    """
    if credential is None:
        credential = get_credential()

    try:
        from azure.mgmt.policyinsights import PolicyInsightsClient  # type: ignore[import]
    except Exception as exc:
        raise RuntimeError(
            "azure-mgmt-policyinsights is required to create PolicyInsightsClient. Install with 'pip install azure-mgmt-policyinsights'."
        ) from exc

    # PolicyInsightsClient doesn't require subscription in constructor
    return PolicyInsightsClient(credential)


if __name__ == "__main__":
    # quick smoke test
    try:
        cred = get_credential()
        sub = get_subscription_id()
        print(f"Using subscription: {sub}")
        # instantiate clients to ensure imports succeed
        _ = create_resource_client(credential=cred, subscription_id=sub)
        _ = create_policyinsights_client(credential=cred)
        print("Clients created successfully.")
    except Exception as e:
        print("Error during smoke test:", e)
