"""Custom exception hierarchy for the garantipay library.

All exceptions raised by this library inherit from :class:`GarantiPayError`,
making it easy to catch all library-specific errors with a single except clause.

Example::

    from garantipay import GarantiClient
    from garantipay.exceptions import GarantiPayError, GarantiPayAPIError

    try:
        response = client.sale(...)
    except GarantiPayAPIError as exc:
        print(f"API returned error: {exc}")
    except GarantiPayError as exc:
        print(f"Library error: {exc}")
"""


class GarantiPayError(Exception):
    """Base exception for all errors raised by the garantipay library.

    Catch this to handle any error originating from this library.
    """


class GarantiPayConnectionError(GarantiPayError):
    """Raised when a network error occurs while communicating with the API.

    This wraps lower-level connection errors (timeouts, DNS failures, etc.)
    to provide a consistent exception interface.
    """


class GarantiPayAPIError(GarantiPayError):
    """Raised when the Garanti BBVA API returns an error response.

    Attributes:
        code: The error code returned by the API (e.g. ``"99"``).
        reason_code: The reason code providing more detail about the error.
        message: Human-readable message from the API.
        sys_err_msg: System-level error message from the API, if available.
    """

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


class GarantiPayValidationError(GarantiPayError):
    """Raised when request parameters fail local validation before being sent.

    This error is raised *before* making any network call, allowing you to
    catch configuration or input mistakes early.
    """


class GarantiPayXMLError(GarantiPayError):
    """Raised when the API response cannot be parsed as valid XML.

    This typically indicates an unexpected response format from the gateway,
    such as an HTML error page instead of the expected GVPSResponse XML.
    """
