#[derive(Debug, Copy, Clone)]
pub enum RpcErrorCode {
    ParseError = -32700,
    InvalidRequest = -32600,
    MethodNotFound = -32601,
    InvalidParams = -32602,
    InternalError = -32603,
    Other = -32000, /* Range -32000 to -32099 is serve defined */
    NotFound = -32004,
    Timeout = -32005,
}

#[derive(Debug)]
pub struct RpcError {
    pub code: RpcErrorCode,
    pub msg: String,
}
impl std::error::Error for RpcError {}

impl std::fmt::Display for RpcError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "RPC error ({} {:?}): {}",
            self.code as i32, self.code, self.msg
        )
    }
}

pub fn rpc_invalid_request(what: String) -> anyhow::Error {
    anyhow::Error::from(RpcError {
        code: RpcErrorCode::InvalidRequest,
        msg: what,
    })
}

pub fn rpc_invalid_params(what: String) -> anyhow::Error {
    anyhow::Error::from(RpcError {
        code: RpcErrorCode::InvalidParams,
        msg: what,
    })
}

pub fn rpc_not_found(what: String) -> anyhow::Error {
    anyhow::Error::from(RpcError {
        code: RpcErrorCode::NotFound,
        msg: what,
    })
}

pub fn rpc_other(what: String) -> anyhow::Error {
    anyhow::Error::from(RpcError {
        code: RpcErrorCode::Other,
        msg: what,
    })
}

pub fn rpc_method_not_found(method: &str) -> anyhow::Error {
    anyhow::Error::from(RpcError {
        code: RpcErrorCode::MethodNotFound,
        msg: format!("unknown method {}", method),
    })
}

pub fn rpc_timeout(duration: &std::time::Duration) -> anyhow::Error {
    anyhow::Error::from(RpcError {
        code: RpcErrorCode::Timeout,
        msg: format!("Timeout after {} seconds", duration.as_secs_f32()),
    })
}

#[derive(Debug)]
pub struct ConnectionError {
    pub msg: String,
}
impl std::error::Error for ConnectionError {}

impl std::fmt::Display for ConnectionError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Full node connection error: {}", self.msg)
    }
}
