"""Cloud provider specifications for CleverAgents.

Defines credential field metadata and provider specifications for
supported cloud providers (AWS, GCP, Azure).

This module is imported by :mod:`cleveragents.resource.handlers.cloud`
and provides the data-only definitions that describe each provider's
required and optional credential fields.

Based on:
    - Issue #343: Cloud Infrastructure Resources
    - Issue #1021: AWS SDK integration
"""

from __future__ import annotations

from dataclasses import dataclass, field


@dataclass(frozen=True)
class _CredentialField:
    """Metadata for a single credential or configuration field."""

    name: str
    env_var: str
    required: bool = True
    sensitive: bool = False
    description: str = ""


@dataclass(frozen=True)
class CloudProviderSpec:
    """Specification of a cloud provider's credential and config fields."""

    provider: str
    description: str
    credential_fields: tuple[_CredentialField, ...]
    metadata_fields: tuple[_CredentialField, ...] = ()
    profile_env_var: str | None = None
    required_fields: frozenset[str] = field(default_factory=frozenset)

    @property
    def all_fields(self) -> tuple[_CredentialField, ...]:
        """Return all fields (credential + metadata)."""
        return self.credential_fields + self.metadata_fields


AWS_SPEC = CloudProviderSpec(
    provider="aws",
    description="Amazon Web Services cloud resource.",
    credential_fields=(
        _CredentialField(
            name="access-key-id",
            env_var="AWS_ACCESS_KEY_ID",
            required=True,
            sensitive=True,
            description="AWS access key ID.",
        ),
        _CredentialField(
            name="secret-access-key",
            env_var="AWS_SECRET_ACCESS_KEY",
            required=True,
            sensitive=True,
            description="AWS secret access key.",
        ),
        _CredentialField(
            name="session-token",
            env_var="AWS_SESSION_TOKEN",
            required=False,
            sensitive=True,
            description="AWS session token (optional, for temporary credentials).",
        ),
    ),
    metadata_fields=(
        _CredentialField(
            name="region",
            env_var="AWS_REGION",
            required=False,
            sensitive=False,
            description="AWS region (e.g. us-east-1).",
        ),
        _CredentialField(
            name="profile",
            env_var="AWS_PROFILE",
            required=False,
            sensitive=False,
            description="AWS profile name from ~/.aws/credentials.",
        ),
    ),
    profile_env_var="AWS_PROFILE",
    required_fields=frozenset({"access-key-id", "secret-access-key"}),
)

GCP_SPEC = CloudProviderSpec(
    provider="gcp",
    description="Google Cloud Platform resource.",
    credential_fields=(
        _CredentialField(
            name="service-account-json-path",
            env_var="GOOGLE_APPLICATION_CREDENTIALS",
            required=True,
            sensitive=True,
            description="Path to GCP service account JSON key file.",
        ),
    ),
    metadata_fields=(
        _CredentialField(
            name="project-id",
            env_var="GCLOUD_PROJECT",
            required=True,
            sensitive=False,
            description="GCP project ID.",
        ),
        _CredentialField(
            name="region",
            env_var="GCP_REGION",
            required=False,
            sensitive=False,
            description="GCP region (e.g. us-central1).",
        ),
    ),
    required_fields=frozenset({"service-account-json-path", "project-id"}),
)

AZURE_SPEC = CloudProviderSpec(
    provider="azure",
    description="Microsoft Azure cloud resource.",
    credential_fields=(
        _CredentialField(
            name="subscription-id",
            env_var="AZURE_SUBSCRIPTION_ID",
            required=True,
            sensitive=True,
            description="Azure subscription ID.",
        ),
        _CredentialField(
            name="tenant-id",
            env_var="AZURE_TENANT_ID",
            required=True,
            sensitive=True,
            description="Azure Active Directory tenant ID.",
        ),
        _CredentialField(
            name="client-id",
            env_var="AZURE_CLIENT_ID",
            required=True,
            sensitive=True,
            description="Azure service principal client ID.",
        ),
        _CredentialField(
            name="client-secret",
            env_var="AZURE_CLIENT_SECRET",
            required=True,
            sensitive=True,
            description="Azure service principal client secret.",
        ),
    ),
    metadata_fields=(
        _CredentialField(
            name="region",
            env_var="AZURE_REGION",
            required=False,
            sensitive=False,
            description="Azure region (e.g. eastus).",
        ),
    ),
    required_fields=frozenset(
        {"subscription-id", "tenant-id", "client-id", "client-secret"}
    ),
)


#: Mapping from provider name to its specification.
CLOUD_PROVIDERS: dict[str, CloudProviderSpec] = {
    "aws": AWS_SPEC,
    "gcp": GCP_SPEC,
    "azure": AZURE_SPEC,
}

#: Provider prefixes for hierarchical type name detection.
_PROVIDER_PREFIXES: tuple[str, ...] = ("aws-", "gcp-", "azure-")
