"""Pure credential service classification and visibility policy."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Literal

_WorkerScope = Literal["shared", "user", "user_agent"]

RUNTIME_BOOTSTRAPPED_CLIENT_CONFIG_KEY = "_oauth_client_runtime_bootstrap"

OAUTH_CREDENTIAL_FIELDS = frozenset(
    {
        "_id_token",
        "_oauth_claims",
        "_oauth_claims_verified",
        "_oauth_provider",
        "_source",
        "access_token",
        "client_id",
        "client_secret",
        "expires_at",
        "expires_in",
        "id_token",
        "refresh_token",
        "scope",
        "scopes",
        "token",
        "token_type",
        "token_uri",
    },
)

_OAUTH_CLIENT_CONFIG_SERVICE_SUFFIX = "_oauth_client"
_OAUTH_TOKEN_SERVICE_SUFFIX = "_oauth"  # noqa: S105
# OAuth provider token services use the *_oauth naming contract. The separate
# *_oauth_client app-client config contract intentionally does not match it.

_LOCAL_ONLY_SHARED_CREDENTIAL_SERVICES = frozenset(
    {
        "desktop",
        "google_calendar",
        "google_docs",
        "google_drive",
        "google_gmail",
        "google_sheets",
        "gmail",
        "homeassistant",
    },
)

_UNSUPPORTED_WORKER_GRANTABLE_CREDENTIALS = frozenset(
    {
        "desktop",
        "google_vertex_adc",
    },
)


def _is_oauth_token_service(service: str) -> bool:
    """Return whether a service name follows the OAuth token naming contract."""
    return service.endswith(_OAUTH_TOKEN_SERVICE_SUFFIX)


@dataclass(frozen=True, slots=True)
class _CredentialServicePolicy:
    """Credential placement decisions for one service in one worker scope."""

    service: str
    worker_scope: _WorkerScope | None
    uses_local_shared_credentials: bool
    uses_primary_runtime_global_credentials: bool
    uses_primary_runtime_scoped_credentials: bool
    uses_primary_runtime_agent_scoped_credentials: bool
    worker_grantable_supported: bool


def credential_service_policy(service: str, worker_scope: _WorkerScope | None) -> _CredentialServicePolicy:
    """Return credential placement policy for one service in one worker scope."""
    is_oauth_token_service = _is_oauth_token_service(service)
    is_local_only = service in _LOCAL_ONLY_SHARED_CREDENTIAL_SERVICES or is_oauth_token_service
    is_primary_runtime_global = is_oauth_client_config_service(service)
    # OAuth tokens carry one external account identity, so a shared-scope agent's
    # connection must stay bound to that agent instead of the deployment-wide store
    # every other agent reads.
    uses_agent_scoped = worker_scope == "shared" and is_oauth_token_service
    return _CredentialServicePolicy(
        service=service,
        worker_scope=worker_scope,
        uses_local_shared_credentials=worker_scope == "shared" and is_local_only and not uses_agent_scoped,
        uses_primary_runtime_global_credentials=is_primary_runtime_global,
        uses_primary_runtime_scoped_credentials=(
            worker_scope in {"user", "user_agent"} and is_local_only and not is_primary_runtime_global
        ),
        uses_primary_runtime_agent_scoped_credentials=uses_agent_scoped,
        worker_grantable_supported=not is_primary_runtime_global
        and not is_oauth_token_service
        and service not in _UNSUPPORTED_WORKER_GRANTABLE_CREDENTIALS,
    )


def is_oauth_client_config_service(service: str) -> bool:
    """Return whether a service name follows the OAuth client config naming contract."""
    return service.endswith(_OAUTH_CLIENT_CONFIG_SERVICE_SUFFIX)


def dashboard_may_edit_oauth_service(*, token_service: bool, tool_config_service: bool) -> bool:
    """Return whether dashboard credential routes may edit one OAuth service role."""
    return tool_config_service and not token_service


def looks_like_oauth_credentials(credentials: dict[str, object]) -> bool:
    """Return whether a credential document appears to contain OAuth token state."""
    return (
        credentials.get("_source") == "oauth"
        or isinstance(credentials.get("_oauth_provider"), str)
        or isinstance(credentials.get("_id_token"), str)
        or isinstance(credentials.get("_oauth_claims"), dict)
    )


def filter_oauth_credential_fields(credentials: dict[str, object]) -> dict[str, object]:
    """Return credentials with OAuth token material and internal fields removed."""
    return {
        key: value
        for key, value in credentials.items()
        if key not in OAUTH_CREDENTIAL_FIELDS and not key.startswith("_")
    }
