//! SDK error types.
//!
//! This module defines the unified error surface exposed by the Tenbin SDK.
//! All errors returned from REST and WebSocket operations are represented by
//! [`ClientError`], which is intentionally coarse-grained to provide stability
//! during the crate’s 0.x lifecycle.

use thiserror::Error;

/// Unified error type returned by this SDK.
///
/// This enum is the single error surface for all REST and WebSocket operations.
///
/// ## Stability (0.x)
/// This crate is currently **0.x**; variants may evolve over time. Prefer matching on
/// broad categories (e.g. authentication vs protocol vs configuration) rather than
/// relying on exhaustive matching.
///
/// ## Guidance
/// - Use `Config` for invalid client configuration (bad URLs, invalid timeouts, etc.).
/// - Use `Auth` for authentication/signing failures.
/// - Use `Protocol` for unexpected or invalid server messages/state transitions.
/// - Use `Transport` for SDK-level transport errors not represented by the underlying
///   HTTP/WebSocket libraries (e.g. invariants around request/connection setup).
#[derive(Debug, Error)]
pub enum ClientError {
    /// HTTP transport error originating from the underlying HTTP client.
    ///
    /// This typically indicates request/response failures such as connection errors,
    /// TLS issues, non-2xx handling at the transport layer, etc.
    #[error("HTTP error: {0}")]
    Http(#[from] reqwest::Error),

    /// WebSocket transport error originating from the underlying WebSocket implementation.
    ///
    /// This includes connection failures, I/O errors, and websocket framing/protocol errors
    /// reported by the underlying library.
    #[error("WebSocket error: {0}")]
    WebSocket(#[from] tokio_tungstenite::tungstenite::Error),

    /// Serialization/deserialization error.
    ///
    /// Returned when JSON payloads cannot be serialized or deserialized according to the
    /// expected schema.
    #[error("Serialization error: {0}")]
    Serde(#[from] serde_json::Error),

    /// Authentication or signing failure.
    ///
    /// This includes failures produced by user-supplied signing logic as well as
    /// authentication failures reported by the platform.
    #[error("Authentication failed: {0}")]
    Auth(String),

    /// SDK-level transport error that is not captured by `Http`/`WebSocket`.
    ///
    /// Use this for transport-related invariants and failures that do not originate from
    /// the underlying HTTP or WebSocket libraries.
    #[error("Transport error: {0}")]
    Transport(String),

    /// Configuration error.
    ///
    /// Returned when client configuration is invalid or internally inconsistent, such as
    /// unsupported URL schemes or invalid timeout values.
    #[error("Config error: {0}")]
    Config(String),

    /// Protocol violation or unexpected server behaviour.
    ///
    /// Indicates that a server response violated protocol expectations, such as an
    /// unexpected message type, invalid state transition, or malformed protocol payload.
    #[error("Protocol violation: {0}")]
    Protocol(String),

    /// Operation timed out.
    ///
    /// Indicates that an operation exceeded the configured timeout before completing.
    #[error("Timeout")]
    Timeout,
}
