//! Error types for service client operations.

use thiserror::Error;

/// Result type for service client operations
pub type ServiceResult<T> = Result<T, ServiceError>;

/// Errors that can occur during service client operations
#[derive(Debug, Error)]
pub enum ServiceError {
    /// HTTP request failed
    #[error("HTTP request failed: {0}")]
    RequestError(#[from] reqwest::Error),

    /// Service returned error response
    #[error("Service error: {status} - {message}")]
    ServiceResponseError {
        /// HTTP status code from service
        status: u16,
        /// Error message from service
        message: String,
    },

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

    /// Machine not found
    #[error("Machine not found: {0}")]
    MachineNotFound(String),

    /// SSH connection error
    #[error("SSH connection failed: {0}")]
    SshConnectionError(String),

    /// SSH command execution failed
    #[error("SSH command failed: {0}")]
    CommandExecutionError(String),

    /// Service unavailable
    #[error("Service unavailable: {0}")]
    ServiceUnavailable(String),
}

impl ServiceError {
    /// Create an error from HTTP status and message
    pub fn from_status(status: u16, message: impl Into<String>) -> Self {
        ServiceError::ServiceResponseError {
            status,
            message: message.into(),
        }
    }

    /// Check if error is a not-found error
    pub fn is_not_found(&self) -> bool {
        matches!(self, ServiceError::MachineNotFound(_))
    }

    /// Check if error is a connection error
    pub fn is_connection_error(&self) -> bool {
        matches!(
            self,
            ServiceError::SshConnectionError(_) | ServiceError::ServiceUnavailable(_)
        )
    }
}
