//! Error types for the tapped crate.

use std::io;

/// The error type for tapped operations.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
    /// I/O error (process/file operations)
    #[error("I/O error: {0}")]
    Io(#[from] io::Error),

    /// HTTP client error
    #[error("HTTP error: {0}")]
    Http(#[from] reqwest::Error),

    /// WebSocket error
    #[error("WebSocket error: {0}")]
    WebSocket(#[from] Box<tokio_tungstenite::tungstenite::Error>),

    /// JSON serialisation/deserialisation error
    #[error("JSON error: {0}")]
    Json(#[from] serde_json::Error),

    /// API error returned by tap server
    #[error("API error (status {status}): {message}")]
    Api {
        /// HTTP status code
        status: u16,
        /// Error message from server
        message: String,
    },

    /// Failed to start the tap process
    #[error("Failed to start tap process: {message}")]
    ProcessStart {
        /// Description of the failure
        message: String,
    },

    /// The tap process exited unexpectedly
    #[error("Tap process exited with code: {code:?}")]
    ProcessExited {
        /// Exit code, if available
        code: Option<i32>,
    },

    /// The event channel was closed
    #[error("Event channel closed")]
    ChannelClosed,

    /// WebSocket is not available because tap is in webhook mode
    #[error("WebSocket not available: tap is in webhook mode")]
    WebhookModeActive,

    /// Invalid URL provided
    #[error("Invalid URL: {0}")]
    InvalidUrl(String),

    /// Operation timed out
    #[error("Operation timed out")]
    Timeout,

    /// URL parse error
    #[error("URL parse error: {0}")]
    UrlParse(#[from] url::ParseError),
}
