"""Custom exception hierarchy for pybyd."""

from __future__ import annotations


class BydError(Exception):
    """Base exception for all pybyd errors."""


class BydConfigError(BydError):
    """Invalid or missing configuration."""


class BydCryptoError(BydError):
    """Encryption or decryption failure."""


class BangcleError(BydCryptoError):
    """Bangcle envelope encode/decode failure."""


class BangcleTableLoadError(BangcleError):
    """Could not load Bangcle lookup tables."""


class BydTransportError(BydError):
    """HTTP-level failure (network, non-200, invalid JSON)."""

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


class BydApiError(BydError):
    """API returned a non-zero code (application-level error)."""

    def __init__(
        self,
        message: str,
        *,
        code: str = "",
        endpoint: str = "",
    ) -> None:
        self.code = code
        self.endpoint = endpoint
        super().__init__(message)


class BydAuthenticationError(BydApiError):
    """Login failed or session expired."""


class BydSessionExpiredError(BydAuthenticationError):
    """Session token rejected by the server.

    Raised when a post-login API call fails with an error code that
    indicates the token is no longer valid (e.g. ``1005``).  The client
    catches this internally to trigger automatic re-authentication.
    """


class BydRemoteControlError(BydApiError):
    """Remote control command failed (controlState=2)."""


class BydControlPasswordError(BydApiError):
    """Remote control command rejected due invalid/locked operation password.

    Covers BYD API codes such as:
    - ``5005`` wrong operation password
    - ``5006`` cloud control temporarily locked for the day
    """


class BydEndpointNotSupportedError(BydApiError):
    """Endpoint not supported for this vehicle/region (e.g. code 1001).

    Raised when the API returns an error code indicating the requested
    endpoint is not available for the user's vehicle model, region, or
    firmware version.  Consumers should stop retrying the endpoint for
    the affected VIN.
    """


class BydRateLimitError(BydApiError):
    """Rate limited — a previous command is still in progress (code 6024).

    This is raised when the server returns code 6024 after exhausting
    all automatic retry attempts.
    """
