// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

//! Copyable, equality-comparable `Error`/`Result` types, wrapping `anyhow`.
//!
//! This module is a drop-in replacement for the `anyhow` crate, with the caveat
//! that not all features are implemented, and it may be slower due to requiring
//! an additional layer of boxing every time it round trips back to an
//! `anyhow::Error`.
//!
//! Downcasting by value will never be supported, because of the way copying is
//! implemented -- via `Arc`.
//!
//! ## Salsa
//!
//! The main motivation for this crate is caching return values which may have
//! an error, such as with Salsa. (Although this applies to any approach to
//! caching, not just Salsa specifically.)
//!
//! For example, a memoized function  which returns an `T` on success, and hides
//! this behind an `Rc` for performance, should return
//! `arc_anyhow::Result<Rc<T>>`, not `Rc<anyhow::Result<T>>`. Because
//! `anyhow::Error` cannot be cloned, `Rc<Result<T, anyhow::Error>>` is very
//! nearly useless, as one cannot create a new `Rc<Result<U, anyhow::Error>>`
//! containing the same error. Error propagation with cached errors requires
//! that the underlying error type

use std::fmt::{Debug, Display};
use std::sync::Arc;

/// A clonable, equality-comparable error type, like `anyhow::Error`.
///
/// `Error` is to `anyhow::Error` as `Rc<T>` is to `Box<T>`.
///
/// Two errors are equal if they are identical (i.e. they both have a common
/// cloned-from ancestor.)
#[derive(Clone)]
pub struct Error(Arc<anyhow::Error>);

impl Error {
    /// Create a new error object from a printable error message.
    pub fn msg<M>(message: M) -> Self
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        Self(Arc::new(anyhow::Error::msg(message)))
    }

    /// Convert this into an `anyhow::Error`.
    ///
    /// This creates an extra layer of pointer indirection and should be avoided
    /// when possible.
    pub fn into_anyhow(self) -> anyhow::Error {
        let std_error: StdError = self.into();
        std_error.into()
    }

    /// Gets the lowest level cause of this error.
    ///
    /// Similar to [`anyhow::Error::root_cause`].
    pub fn root_cause(&self) -> &(dyn std::error::Error + 'static) {
        // This crate's `StdError` type is private, so recurse into it to get an
        // error the caller might expect to find.
        let e = self.0.root_cause();
        if let Some(e) = e.downcast_ref::<StdError>() {
            e.0.root_cause()
        } else {
            e
        }
    }

    pub fn context<C>(self, context: C) -> Self
    where
        C: Display + Send + Sync + 'static,
    {
        self.into_anyhow().context(context).into()
    }

    pub fn downcast_ref<E>(&self) -> Option<&E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        self.0.downcast_ref()
    }
}

impl PartialEq for Error {
    fn eq(&self, other: &Self) -> bool {
        Arc::ptr_eq(&self.0, &other.0)
    }
}

impl Eq for Error {}

impl std::hash::Hash for Error {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        Arc::as_ptr(&self.0).hash(state)
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        Display::fmt(&*self.0, f)
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        Debug::fmt(&*self.0, f)
    }
}

// Note: this blanket impl prevents Error from implementing `std::error::Error`.
// We need all "normal" errors -- say, all those that implemen
// `std::error::Error` -- to be convertible to `Error`, but this would cause
// overlapping impls if `Error` itself implemented `std::error::Error`. For that
// reason, both `anyhow` and `arc_anyhow` don't actually implement the error
// trait!
impl<T> From<T> for Error
where
    T: Into<anyhow::Error>,
{
    fn from(e: T) -> Self {
        Error(Arc::new(e.into()))
    }
}

/// Helper type which can be converted to `anyhow::Error` directly, by
/// implementing `std::error::Error`.
///
/// `arc_anyhow::Error` cannot itself implement `std::error::Error` for the same
/// reason that `anyhow::Error` cannot -- at various places it produces blanket
/// impl conflicts and other metaprogramming difficulties.
#[derive(Clone)]
struct StdError(Arc<anyhow::Error>);

impl Display for StdError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        Display::fmt(&*self.0, f)
    }
}

impl Debug for StdError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        Debug::fmt(&*self.0, f)
    }
}

impl std::error::Error for StdError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        self.0.source()
    }
}

impl From<Error> for StdError {
    fn from(e: Error) -> Self {
        StdError(e.0)
    }
}

pub type Result<T, E = Error> = std::result::Result<T, E>;

/// A replacement for anyhow::Context.
///
/// (`anyhow::Context` cannot be used because it is sealed. Even if it weren't
/// sealed, it returns `anyhow::Result` instead of `arc_anyhow::Result`.)
pub trait Context<T, E> {
    fn context<C>(self, context: C) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static;
    fn with_context<C, F>(self, f: F) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
        F: FnOnce() -> C;
}

// Note: can't use `where Result<T, E>: anyhow::Context<T, E>` due to coherence
// rules. The bounds for `anyhow::Context` can change to overlap.
// Instead, we implement `Context` for everything *except* `anyhow::Error`!

impl<T, E> Context<T, E> for Result<T, E>
where
    E: std::error::Error + Send + Sync + 'static,
{
    fn context<C>(self, context: C) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
    {
        anyhow::Context::context(self, context).map_err(|e| e.into())
    }
    fn with_context<C, F>(self, f: F) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
        F: FnOnce() -> C,
    {
        anyhow::Context::with_context(self, f).map_err(|e| e.into())
    }
}

impl<T> Context<T, std::convert::Infallible> for Option<T> {
    fn context<C>(self, context: C) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
    {
        anyhow::Context::context(self, context).map_err(|e| e.into())
    }
    fn with_context<C, F>(self, f: F) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
        F: FnOnce() -> C,
    {
        anyhow::Context::with_context(self, f).map_err(|e| e.into())
    }
}

impl<T> Context<T, Error> for Result<T, Error> {
    fn context<C>(self, context: C) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
    {
        let e: Result<T, StdError> = self.map_err(|e| e.into());
        e.context(context)
    }
    fn with_context<C, F>(self, f: F) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
        F: FnOnce() -> C,
    {
        let e: Result<T, StdError> = self.map_err(|e| e.into());
        e.with_context(f)
    }
}

#[doc(hidden)]
pub mod macro_internal {
    pub use ::anyhow;
}

/// An `anyhow` macro which returns an `RcError` instead of an `anyhow::Error`.
#[macro_export]
macro_rules! anyhow {
    ($($t:tt)*) => {
        {
            // specifically constrain to Error, so that type inference works maximally.
            $crate::Error::from($crate::macro_internal::anyhow::anyhow!($($t)*))
        }
    }
}

/// An `ensure` macro which returns an `Result` instead of an
/// `anyhow::Result`.
#[macro_export]
macro_rules! ensure {
    ($($t:tt)*) => {
        {
            let result = || -> $crate::macro_internal::anyhow::Result<()> {
                $crate::macro_internal::anyhow::ensure!($($t)*);
                Ok(())
            }();
            if let Err(e) = result {
                // specifically constrain to Error, so that type inference works maximally.
                return $crate::Result::Err($crate::Error::from(e));
            }
        }
    }
}

/// A `bail` macro which returns an `Result` instead of an
/// `anyhow::Result`.
#[macro_export]
macro_rules! bail {
    ($($t:tt)*) => {
        return $crate::Result::Err($crate::anyhow!($($t)*))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use googletest::prelude::*;

    use super::Result as AAResult;

    #[gtest]
    fn test_result_context() {
        let result: AAResult<()> = AAResult::Err(anyhow!("Something went wrong!"))
            .with_context(|| "context 1")
            .context("context 2");
        let err = result.unwrap_err();

        assert_eq!(&format!("{err}"), "context 2",);
        assert_eq!(&format!("{err:#}"), "context 2: context 1: Something went wrong!",);
        assert_eq!(
            &format!("{err:?}"),
            "context 2\n\n\
                Caused by:\
                \n    0: context 1\
                \n    1: Something went wrong!\
                ",
        );
        // This is probably a bad idea to actually test, for stability reasons,
        // but the Debug representation is also threaded through
        // unchanged:
        //
        // ```
        // assert_eq!(
        //     &format!("{err:#?}"),
        //     "Error {\
        //     \n    context: \"context 2\",\
        //     \n    source: Error {\
        //     \n        context: \"context 1\",\
        //     \n        source: \"Something went wrong!\",\
        //     \n    },\
        //     \n}",
        // );
        // ```
    }
    #[gtest]
    fn test_error_context() {
        let err = anyhow!("Something went wrong!").context("context 1").context("context 2");
        assert_eq!(&format!("{err}"), "context 2",);
        assert_eq!(&format!("{err:#}"), "context 2: context 1: Something went wrong!",);
        assert_eq!(
            &format!("{err:?}"),
            "context 2\n\n\
                Caused by:\
                \n    0: context 1\
                \n    1: Something went wrong!\
                ",
        );
    }

    #[gtest]
    fn test_macro_anyhow() {
        assert_eq!(&format!("{}", anyhow!("message")), "message");
    }

    #[gtest]
    fn test_macro_bail() {
        let err = (|| -> AAResult<()> { bail!("message") })().unwrap_err();
        assert_eq!(&format!("{err}"), "message");
    }

    #[gtest]
    fn test_macro_ensure() {
        let err = (|| {
            ensure!(false, "message");
            Ok(())
        })()
        .unwrap_err();
        assert_eq!(&format!("{err}"), "message");
    }

    #[gtest]
    fn test_cloned_equality() {
        fn hash(e: &Error) -> u64 {
            use std::hash::Hash;
            use std::hash::Hasher;
            let mut hasher = std::collections::hash_map::DefaultHasher::new();
            e.hash(&mut hasher);
            hasher.finish()
        }

        let e1 = anyhow!("message");
        let e2 = e1.clone();
        assert_eq!(e1, e2);
        assert_eq!(hash(&e1), hash(&e2));
    }
}
