"""
Error classification enums for the Lumos Connector SDK.

ConnectorErrorFault   — *who* is responsible for the error
ConnectorErrorCategory — *what kind* of action the caller should take
"""

from __future__ import annotations

from enum import Enum

from connector_sdk_types.errors.codes import ConnectorErrorCode


class ConnectorErrorFault(str, Enum):
    """
    Who is responsible for the error.
    """

    CALLER = "caller"
    """The request from the initiating system was invalid.
    Examples: bad input, missing required field, unsupported operation."""

    CONNECTOR = "connector"
    """A bug or misconfiguration inside the connector itself.
    Examples: internal_error, invalid_response (connector misread the upstream schema)."""

    UPSTREAM = "upstream"
    """The upstream third-party API, end system or service caused the failure.
    Examples: auth failures, rate limits, 5xx server errors, end system timeout."""

    INFRASTRUCTURE = "infrastructure"
    """The network or transport layer caused the failure, independent of the upstream API.
    Examples: DNS failure, TCP timeout, connection refused."""

    UNKNOWN = "unknown"
    """Fault party cannot be determined from available information.
    Used as a safe fallback; prefer a specific value wherever possible."""


class ConnectorErrorCategory(str, Enum):
    """
    The action classification — what the caller should do in response to this error.
    """

    AUTHENTICATION = "authentication"
    """Credential problem - re-authenticate or refresh the token.
    Codes: authentication_expired, creds_revoked."""

    AUTHORIZATION = "authorization"
    """Permissions problem - credentials are valid but lack required scope. Re-connection is most likely required.
    Codes: permission_denied, unauthorized."""

    TRANSIENT = "transient"
    """Temporary failure - safe to retry.
    Codes: rate_limit, bad_gateway, service_error, connection_timeout,
    request_timeout, connection_rejected, connection_closed."""

    CLIENT = "client"
    """Caller/input error — fix the request; do not retry.
    Codes: bad_request, invalid_value, unknown_value, not_found,
    invalid_page_token, integration_missing_parameter, conflict."""

    INTERNAL = "internal"
    """Connector bug or misconfiguration — requires a code fix; do not retry.
    Codes: internal_error, invalid_response, unsupported_operation."""


"""
Following dicts map every ConnectorErrorCode to its fault party and action category.
"""

CODE_FAULT_MAP: dict[ConnectorErrorCode, ConnectorErrorFault] = {
    ConnectorErrorCode.BAD_REQUEST: ConnectorErrorFault.CALLER,
    ConnectorErrorCode.INVALID_VALUE: ConnectorErrorFault.CALLER,
    ConnectorErrorCode.UNKNOWN_VALUE: ConnectorErrorFault.CALLER,
    ConnectorErrorCode.NOT_FOUND: ConnectorErrorFault.CALLER,
    ConnectorErrorCode.CONFLICT: ConnectorErrorFault.CALLER,
    ConnectorErrorCode.INVALID_PAGE_TOKEN: ConnectorErrorFault.CALLER,
    ConnectorErrorCode.INTEGRATION_MISSING_PARAMETER: ConnectorErrorFault.CALLER,
    ConnectorErrorCode.UNSUPPORTED_OPERATION: ConnectorErrorFault.CONNECTOR,
    ConnectorErrorCode.UNAUTHORIZED: ConnectorErrorFault.UPSTREAM,
    ConnectorErrorCode.AUTHENTICATION_EXPIRED: ConnectorErrorFault.UPSTREAM,
    ConnectorErrorCode.CREDS_REVOKED: ConnectorErrorFault.UPSTREAM,
    ConnectorErrorCode.PERMISSION_DENIED: ConnectorErrorFault.UPSTREAM,
    ConnectorErrorCode.RATE_LIMIT: ConnectorErrorFault.UPSTREAM,
    ConnectorErrorCode.BAD_GATEWAY: ConnectorErrorFault.UPSTREAM,
    ConnectorErrorCode.SERVICE_ERROR: ConnectorErrorFault.UPSTREAM,
    ConnectorErrorCode.REQUEST_TIMEOUT: ConnectorErrorFault.UPSTREAM,
    ConnectorErrorCode.CONNECTION_TIMEOUT: ConnectorErrorFault.INFRASTRUCTURE,
    ConnectorErrorCode.CONNECTION_REJECTED: ConnectorErrorFault.INFRASTRUCTURE,
    ConnectorErrorCode.CONNECTION_CLOSED: ConnectorErrorFault.INFRASTRUCTURE,
    ConnectorErrorCode.INTERNAL_ERROR: ConnectorErrorFault.CONNECTOR,
    ConnectorErrorCode.INVALID_RESPONSE: ConnectorErrorFault.CONNECTOR,
}

CODE_CATEGORY_MAP: dict[ConnectorErrorCode, ConnectorErrorCategory] = {
    ConnectorErrorCode.BAD_REQUEST: ConnectorErrorCategory.CLIENT,
    ConnectorErrorCode.INVALID_VALUE: ConnectorErrorCategory.CLIENT,
    ConnectorErrorCode.UNKNOWN_VALUE: ConnectorErrorCategory.CLIENT,
    ConnectorErrorCode.NOT_FOUND: ConnectorErrorCategory.CLIENT,
    ConnectorErrorCode.CONFLICT: ConnectorErrorCategory.CLIENT,
    ConnectorErrorCode.INVALID_PAGE_TOKEN: ConnectorErrorCategory.CLIENT,
    ConnectorErrorCode.INTEGRATION_MISSING_PARAMETER: ConnectorErrorCategory.CLIENT,
    ConnectorErrorCode.UNSUPPORTED_OPERATION: ConnectorErrorCategory.INTERNAL,
    ConnectorErrorCode.UNAUTHORIZED: ConnectorErrorCategory.AUTHENTICATION,
    ConnectorErrorCode.AUTHENTICATION_EXPIRED: ConnectorErrorCategory.AUTHENTICATION,
    ConnectorErrorCode.CREDS_REVOKED: ConnectorErrorCategory.AUTHENTICATION,
    ConnectorErrorCode.PERMISSION_DENIED: ConnectorErrorCategory.AUTHORIZATION,
    ConnectorErrorCode.RATE_LIMIT: ConnectorErrorCategory.TRANSIENT,
    ConnectorErrorCode.BAD_GATEWAY: ConnectorErrorCategory.TRANSIENT,
    ConnectorErrorCode.SERVICE_ERROR: ConnectorErrorCategory.TRANSIENT,
    ConnectorErrorCode.CONNECTION_TIMEOUT: ConnectorErrorCategory.TRANSIENT,
    ConnectorErrorCode.REQUEST_TIMEOUT: ConnectorErrorCategory.TRANSIENT,
    ConnectorErrorCode.CONNECTION_REJECTED: ConnectorErrorCategory.TRANSIENT,
    ConnectorErrorCode.CONNECTION_CLOSED: ConnectorErrorCategory.TRANSIENT,
    ConnectorErrorCode.INTERNAL_ERROR: ConnectorErrorCategory.INTERNAL,
    ConnectorErrorCode.INVALID_RESPONSE: ConnectorErrorCategory.INTERNAL,
}
