//! Privacy SDK errors

use std::fmt;

/// Privacy SDK result type
pub type Result<T> = std::result::Result<T, PrivacyError>;

/// Privacy SDK error
#[derive(Debug)]
pub enum PrivacyError {
    /// HTTP request error
    Request(String),
    /// Invalid response
    Response(String),
    /// Serialization error
    Serialization(String),
    /// API error
    Api {
        message: String,
        code: Option<String>,
        status_code: Option<u16>,
    },
    /// Client is closed
    Closed,
}

impl fmt::Display for PrivacyError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            PrivacyError::Request(msg) => write!(f, "Request error: {}", msg),
            PrivacyError::Response(msg) => write!(f, "Response error: {}", msg),
            PrivacyError::Serialization(msg) => write!(f, "Serialization error: {}", msg),
            PrivacyError::Api { message, code, status_code } => {
                write!(f, "API error: {}", message)?;
                if let Some(c) = code {
                    write!(f, " (code: {})", c)?;
                }
                if let Some(s) = status_code {
                    write!(f, " (status: {})", s)?;
                }
                Ok(())
            }
            PrivacyError::Closed => write!(f, "Client has been closed"),
        }
    }
}

impl std::error::Error for PrivacyError {}

impl From<reqwest::Error> for PrivacyError {
    fn from(err: reqwest::Error) -> Self {
        PrivacyError::Request(err.to_string())
    }
}

impl From<serde_json::Error> for PrivacyError {
    fn from(err: serde_json::Error) -> Self {
        PrivacyError::Serialization(err.to_string())
    }
}
