// Copyright 2017-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Error types

use core::fmt;

#[cfg(feature="std")]
use std::error::Error as stdError;

/// Error kind which can be matched over.
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum ErrorKind {
    /// Feature is not available; not recoverable.
    /// 
    /// This is the most permanent failure type and implies the error cannot be
    /// resolved simply by retrying (e.g. the feature may not exist in this
    /// build of the application or on the current platform).
    Unavailable,
    /// General failure; there may be a chance of recovery on retry.
    /// 
    /// This is the catch-all kind for errors from known and unknown sources
    /// which do not have a more specific kind / handling method.
    /// 
    /// It is suggested to retry a couple of times or retry later when
    /// handling; some error sources may be able to resolve themselves,
    /// although this is not likely.
    Unexpected,
    /// A transient failure which likely can be resolved or worked around.
    /// 
    /// This error kind exists for a few specific cases where it is known that
    /// the error likely can be resolved internally, but is reported anyway.
    Transient,
    /// Not ready yet: recommended to try again a little later.
    /// 
    /// This error kind implies the generator needs more time or needs some
    /// other part of the application to do something else first before it is
    /// ready for use; for example this may be used by external generators
    /// which require time for initialization.
    NotReady,
    #[doc(hidden)]
    __Nonexhaustive,
}

impl ErrorKind {
    /// True if this kind of error may resolve itself on retry.
    /// 
    /// See also `should_wait()`.
    pub fn should_retry(self) -> bool {
        self != ErrorKind::Unavailable
    }
    
    /// True if we should retry but wait before retrying
    /// 
    /// This implies `should_retry()` is true.
    pub fn should_wait(self) -> bool {
        self == ErrorKind::NotReady
    }
    
    /// A description of this error kind
    pub fn description(self) -> &'static str {
        match self {
            ErrorKind::Unavailable => "permanently unavailable",
            ErrorKind::Unexpected => "unexpected failure",
            ErrorKind::Transient => "transient failure",
            ErrorKind::NotReady => "not ready yet",
            ErrorKind::__Nonexhaustive => unreachable!(),
        }
    }
}


/// Error type of random number generators
/// 
/// This is a relatively simple error type, designed for compatibility with and
/// without the Rust `std` library. It embeds a "kind" code, a message (static
/// string only), and an optional chained cause (`std` only). The `kind` and
/// `msg` fields can be accessed directly; cause can be accessed via
/// `std::error::Error::cause` or `Error::take_cause`. Construction can only be
/// done via `Error::new` or `Error::with_cause`.
#[derive(Debug)]
pub struct Error {
    /// The error kind
    pub kind: ErrorKind,
    /// The error message
    pub msg: &'static str,
    #[cfg(feature="std")]
    cause: Option<Box<stdError + Send + Sync>>,
}

impl Error {
    /// Create a new instance, with specified kind and a message.
    pub fn new(kind: ErrorKind, msg: &'static str) -> Self {
        #[cfg(feature="std")] {
            Error { kind: kind, msg: msg, cause: None }
        }
        #[cfg(not(feature="std"))] {
            Error { kind: kind, msg: msg }
        }
    }
    
    /// Create a new instance, with specified kind, message, and a
    /// chained cause.
    /// 
    /// Note: `stdError` is an alias for `std::error::Error`.
    /// 
    /// If not targetting `std` (i.e. `no_std`), this function is replaced by
    /// another with the same prototype, except that there are no bounds on the
    /// type `E` (because both `Box` and `stdError` are unavailable), and the
    /// `cause` is ignored.
    #[cfg(feature="std")]
    pub fn with_cause<E>(kind: ErrorKind, msg: &'static str, cause: E) -> Self
        where E: Into<Box<stdError + Send + Sync>>
    {
        Error { kind: kind, msg: msg, cause: Some(cause.into()) }
    }
    
    /// Create a new instance, with specified kind, message, and a
    /// chained cause.
    /// 
    /// In `no_std` mode the *cause* is ignored.
    #[cfg(not(feature="std"))]
    pub fn with_cause<E>(kind: ErrorKind, msg: &'static str, _cause: E) -> Self {
        Error { kind: kind, msg: msg }
    }
    
    /// Take the cause, if any. This allows the embedded cause to be extracted.
    /// This uses `Option::take`, leaving `self` with no cause.
    #[cfg(feature="std")]
    pub fn take_cause(&mut self) -> Option<Box<stdError + Send + Sync>> {
        self.cause.take()
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        #[cfg(feature="std")] {
            if let Some(ref cause) = self.cause {
                return write!(f, "{} ({}); cause: {}",
                        self.msg, self.kind.description(), cause);
            }
        }
        write!(f, "{} ({})", self.msg, self.kind.description())
    }
}

#[cfg(feature="std")]
impl stdError for Error {
    fn description(&self) -> &str {
        self.msg
    }

    fn cause(&self) -> Option<&stdError> {
        self.cause.as_ref().map(|e| e.as_ref() as &stdError)
    }
}
