from __future__ import annotations

from fastmcp.exceptions import ToolError


class KeycloakClientError(Exception):
    """Base error for all Keycloak client operations."""

    def __init__(self, message: str = "", status_code: int | None = None):
        self.status_code = status_code
        super().__init__(message)


class KeycloakAuthError(KeycloakClientError):
    """401 — token expired or invalid."""


class KeycloakForbiddenError(KeycloakClientError):
    """403 — insufficient permissions (missing realm-management roles)."""


class KeycloakNotFoundError(KeycloakClientError):
    """404 — resource not found."""


class KeycloakConflictError(KeycloakClientError):
    """409 — duplicate name/ID."""


class KeycloakValidationError(KeycloakClientError):
    """400 — malformed or invalid parameters."""


class KeycloakServerError(KeycloakClientError):
    """500+ — server-side error."""


def translate_error(
    error: Exception,
    *,
    resource_type: str | None = None,
    resource_id: str | None = None,
) -> ToolError:
    """Translate a Keycloak client error into an AI-friendly ToolError."""
    resource_desc = resource_type or "resource"
    if resource_id is not None:
        resource_desc = f"{resource_desc} '{resource_id}'"

    if isinstance(error, KeycloakNotFoundError):
        return ToolError(
            f"Keycloak {resource_desc} not found. "
            f"Use kc_list_realms or kc_list_users to discover available resources."
        )
    if isinstance(error, KeycloakAuthError):
        return ToolError(
            f"Keycloak authentication expired for {resource_desc}. "
            f"Run kc_auth_login to re-authenticate."
        )
    if isinstance(error, KeycloakForbiddenError):
        return ToolError(
            f"Insufficient Keycloak permissions for {resource_desc}. "
            f"The authenticated user needs realm-management roles "
            f"(manage-users, manage-realm, view-realm). "
            f"Contact your Keycloak administrator."
        )
    if isinstance(error, KeycloakConflictError):
        return ToolError(
            f"Keycloak {resource_desc} already exists. "
            f"Use a different name or update the existing resource."
        )
    if isinstance(error, KeycloakValidationError):
        return ToolError(f"Keycloak validation failed for {resource_desc}: {error}")
    if isinstance(error, KeycloakServerError):
        return ToolError(
            f"Keycloak server error for {resource_desc}: {error}. "
            f"This is a backend issue — retry or check kc_connection_status."
        )
    return ToolError(f"Keycloak error for {resource_desc}: {error}")
