//! Error types used by this crate

use std::{
    fmt::{self, Display},
    io,
    str::Utf8Error,
};
use thiserror::Error;

/// Create a new error (of a given enum variant) with a formatted message
macro_rules! format_err {
    ($kind:path, $msg:expr) => {
        crate::error::Error::new(
            $kind,
            &$msg.to_string()
        )
    };
    ($kind:path, $fmt:expr, $($arg:tt)+) => {
        format_err!($kind, &format!($fmt, $($arg)+))
    };
}

/// Create and return an error with a formatted message
macro_rules! fail {
    ($kind:path, $msg:expr) => {
        return Err(format_err!($kind, $msg).into())
    };
    ($kind:path, $fmt:expr, $($arg:tt)+) => {
        fail!($kind, &format!($fmt, $($arg)+))
    };
}

/// Result alias with the `rustsec` crate's `Error` type.
pub type Result<T> = std::result::Result<T, Error>;

/// Error type
#[derive(Debug)]
pub struct Error {
    /// Kind of error
    kind: ErrorKind,

    /// Message providing a more specific explanation than `self.kind`.
    ///
    /// This may be a complete error by itself, or it may provide context for `self.source`.
    msg: String,

    /// Cause of this error.
    ///
    /// The specific type of this error should not be considered part of the stable interface of
    /// this crate.
    source: Option<Box<dyn std::error::Error + Send + Sync>>,
}

impl Error {
    /// Creates a new [`Error`](struct@Error) with the given description.
    ///
    /// Do not use this for wrapping [`std::error::Error`]; use [`Error::with_source()`] instead.
    pub fn new<S: ToString>(kind: ErrorKind, description: &S) -> Self {
        // TODO: In a semver-breaking release, deprecate accepting anything but a `String`,
        // or maybe `AsRef<str>`. This will discourage putting error types in the `description`
        // position, which makes it impossible to retrieve their `.source()` info. It will also
        // avoid an unnecessary clone in the common case where `S` is already a `String`.
        Self {
            kind,
            msg: description.to_string(),
            source: None,
        }
    }

    /// Creates a new [`Error`](struct@Error) whose [`std::error::Error::source()`] is `source`.
    ///
    /// `msg` should describe the operation which failed so as to give context for how `source`
    /// is a meaningful error. For example, if `source` is a [`std::io::Error`] from trying to
    /// read a file, then `msg` should include the path of the file and why the file is relevant.
    pub fn with_source<E: std::error::Error + Send + Sync + 'static>(
        kind: ErrorKind,
        msg: String,
        source: E,
    ) -> Self {
        Self {
            kind,
            msg,
            source: Some(Box::new(source)),
        }
    }

    /// Obtain the inner `ErrorKind` for this error
    pub fn kind(&self) -> ErrorKind {
        self.kind
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}: {}", self.kind, self.msg)
    }
}

impl std::error::Error for Error {
    /// The lower-level source of this error, if any.
    ///
    /// The specific type of the returned error should not be considered part of the stable
    /// interface of this crate; prefer to use this only for displaying error information.
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match &self.source {
            Some(boxed_error) => Some(&**boxed_error),
            None => None,
        }
    }
}

/// Custom error type for this library
#[derive(Copy, Clone, Debug, Error, Eq, PartialEq)]
#[non_exhaustive]
pub enum ErrorKind {
    /// Invalid argument or parameter
    #[error("bad parameter")]
    BadParam,

    /// Error performing an automatic fix
    #[cfg(feature = "fix")]
    #[cfg_attr(docsrs, doc(cfg(feature = "fix")))]
    #[error("fix failed")]
    Fix,

    /// An error occurred performing an I/O operation (e.g. network, file)
    #[error("I/O operation failed")]
    Io,

    /// Not found
    #[error("not found")]
    NotFound,

    /// Unable to acquire filesystem lock
    #[error("unable to acquire filesystem lock")]
    LockTimeout,

    /// Couldn't parse response data
    #[error("parse error")]
    Parse,

    /// Registry-related error
    #[error("registry")]
    Registry,

    /// Git operation failed
    #[error("git operation failed")]
    Repo,

    /// Errors related to versions
    #[error("bad version")]
    Version,
}

impl From<Utf8Error> for Error {
    fn from(other: Utf8Error) -> Self {
        format_err!(ErrorKind::Parse, &other)
    }
}

impl From<cargo_lock::Error> for Error {
    fn from(other: cargo_lock::Error) -> Self {
        format_err!(ErrorKind::Io, &other)
    }
}

impl From<fmt::Error> for Error {
    fn from(other: fmt::Error) -> Self {
        format_err!(ErrorKind::Io, &other)
    }
}

impl From<io::Error> for Error {
    fn from(other: io::Error) -> Self {
        format_err!(ErrorKind::Io, &other)
    }
}

impl Error {
    /// Converts from [`tame_index::Error`] to our `Error`.
    ///
    /// This is a separate function instead of a `From` impl
    /// because a trait impl would leak into the public API,
    /// and we need to keep it private because `tame_index` semver
    /// will be bumped frequently and we don't want to bump `rustsec` semver
    /// every time it changes.
    #[cfg(feature = "git")]
    pub(crate) fn from_tame(err: tame_index::Error) -> Self {
        // Separate lock timeouts into their own LockTimeout variant.
        use tame_index::utils::flock::LockError;
        match err {
            tame_index::Error::Lock(lock_err) => match &lock_err.source {
                LockError::TimedOut | LockError::Contested => {
                    format_err!(ErrorKind::LockTimeout, "{}", lock_err)
                }
                _ => format_err!(ErrorKind::Io, "{}", lock_err),
            },
            other => format_err!(ErrorKind::Registry, "{}", other),
        }
    }

    /// Converts from [`toml::de::Error`] to our `Error`.
    ///
    /// This is used so rarely that there is no need to `impl From`,
    /// and this way we can avoid leaking it into the public API.
    pub(crate) fn from_toml(other: toml::de::Error) -> Self {
        format_err!(crate::ErrorKind::Parse, &other)
    }
}

impl From<toml::ser::Error> for Error {
    fn from(other: toml::ser::Error) -> Self {
        format_err!(ErrorKind::Parse, &other)
    }
}
