// 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

use regex::Regex;
use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::fmt::{self, Arguments, Display, Formatter};
use std::rc::Rc;

use serde::Serialize;

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

fn to_string_with_cause(error: &arc_anyhow::Error) -> String {
    format!("{:#}", error)
}

fn errors_to_string(errors: &[arc_anyhow::Error]) -> String {
    errors.iter().map(to_string_with_cause).collect::<Vec<_>>().join("\n")
}

/// A list of errors that, when converted to an `anyhow::Error`, can still be
/// individually reported when used with `ErrorReport`.
#[derive(Debug, Clone)]
pub struct ErrorList {
    errors: Vec<arc_anyhow::Error>,
}

impl From<Vec<arc_anyhow::Error>> for ErrorList {
    fn from(errors: Vec<arc_anyhow::Error>) -> Self {
        Self { errors }
    }
}

impl Display for ErrorList {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        f.write_str(&errors_to_string(&self.errors))
    }
}

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

/// An error that stores its format string as well as the formatted message.
#[derive(Debug, Clone)]
pub struct FormattedError {
    pub fmt: Cow<'static, str>,
    pub message: Cow<'static, str>,
}

impl FormattedError {
    pub fn new_static(fmt: &'static str, args: Arguments) -> arc_anyhow::Error {
        arc_anyhow::Error::from(anyhow::Error::from(match args.as_str() {
            // This format string has no parameters to format at runtime.
            // Note: The compiler can perform optimizations to return `Some`, when even when
            // `fmt` contains placeholders, so we store `fmt` instead of `s` for `fmt` field.
            Some(s) => Self { fmt: Cow::Borrowed(fmt), message: Cow::Borrowed(s) },
            // This format string has parameters and must be formatted.
            None => Self { fmt: Cow::Borrowed(fmt), message: Cow::Owned(fmt::format(args)) },
        }))
    }

    pub fn new_dynamic(err: impl Display) -> arc_anyhow::Error {
        // Use the whole error as the format string. This is preferable to
        // grouping all dynamic errors under the "{}" format string.
        let message = format!("{}", err);
        arc_anyhow::Error::from(anyhow::Error::from(Self {
            fmt: Cow::Owned(message.clone()),
            message: Cow::Owned(message),
        }))
    }
}

impl Display for FormattedError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{}", self.message)
    }
}

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

/// Evaluates to an [`arc_anyhow::Error`].
///
/// Otherwise similar to [`anyhow::anyhow`].
#[macro_export]
macro_rules! anyhow {
    ($fmt:literal $(,)?) => {
        $crate::FormattedError::new_static(
            #[allow(clippy::literal_string_with_formatting_args)] $fmt,
            $crate::macro_internal::format_args!($fmt),
        )
    };
    ($err:expr $(,)?) => {
        $crate::FormattedError::new_dynamic($err)
    };
    ($fmt:expr, $($arg:tt)*) => {
        $crate::FormattedError::new_static(
            #[allow(clippy::literal_string_with_formatting_args)] $fmt,
            $crate::macro_internal::format_args!($fmt, $($arg)*),
        )
    };
}

/// Returns a [`Result::Err`] containing an [`arc_anyhow::Error`].
///
/// Otherwise similar to [`anyhow::bail`].
#[macro_export]
macro_rules! bail {
    ($fmt:literal $(,)?) => {
        return Err($crate::anyhow!($fmt))
    };
    ($err:expr $(,)?) => {
        return Err($crate::anyhow!($err))
    };
    ($fmt:expr, $($arg:tt)*) => {
        return Err($crate::anyhow!($fmt, $($arg)*))
    };
}

/// Returns a [`Result::Err`] containing an [`arc_anyhow::Error`] if the given
/// condition evaluates to false.
///
/// Otherwise similar to [`anyhow::ensure`].
#[macro_export]
macro_rules! ensure {
    ($cond:expr, $fmt:literal $(,)?) => {
        if !$cond { $crate::bail!($fmt); }
    };
    ($cond:expr, $err:expr $(,)?) => {
        if !$cond { $crate::bail!($err); }
    };
    ($cond:expr, $fmt:expr, $($arg:tt)*) => {
        if !$cond { $crate::bail!($fmt, $($arg)*); }
    };
}

/// An interface by which errors can be recorded to generate a structured
/// report.
pub trait ErrorReporting {
    fn report(&self, error: &arc_anyhow::Error);
}

pub struct IgnoreErrors;

impl ErrorReporting for IgnoreErrors {
    fn report(&self, _: &arc_anyhow::Error) {}
}

fn hide_unstable_details(input: &str) -> String {
    // Remove line:column in def id
    let regex = Regex::new(r"DefId\(\d+:\d+ ~ ").unwrap();
    let res = regex.replace_all(input, "DefId(").to_string();

    // Remove all hash id in the def id
    let regex = Regex::new(r"\[[0-9a-fA-F]{4}\]").unwrap();
    regex.replace_all(res.as_str(), "").to_string()
}

/// An aggregate of zero or more errors.
#[derive(Default, Debug)]
pub struct ErrorReport {
    // The interior mutability / borrow_mut will never panic: it is never borrowed for longer than
    // a method call, and the methods do not call each other.
    map: RefCell<BTreeMap<Cow<'static, str>, ErrorReportEntry>>,
}

impl ErrorReport {
    pub fn new() -> Self {
        Self::default()
    }

    /// If `enable` is true, returns a pair of an `ErrorReport` and a `dyn
    /// ErrorReporting` that will report errors into the `ErrorReport`.
    ///
    /// If `enable` is false, returns `None` with a `dyn ErrorReporting` that
    /// will ignore errors.
    pub fn new_rc_or_ignore(enable: bool) -> (Option<Rc<Self>>, Rc<dyn ErrorReporting>) {
        if enable {
            let this = Rc::new(Self::default());
            (Some(this.clone()), this)
        } else {
            (None, Rc::new(IgnoreErrors))
        }
    }

    pub fn to_json_string(&self) -> String {
        serde_json::to_string_pretty(&*self.map.borrow())
            .expect("ErrorReporting serialization to JSON failed unexpectedly")
    }
}

impl ErrorReporting for ErrorReport {
    fn report(&self, error: &arc_anyhow::Error) {
        let root_cause = error.root_cause();
        if let Some(error) = root_cause.downcast_ref::<FormattedError>() {
            let sample_message = if error.message != error.fmt { &*error.message } else { "" };
            self.map
                .borrow_mut()
                .entry(error.fmt.clone())
                .or_default()
                .add(Cow::Owned(hide_unstable_details(sample_message)));
        } else if let Some(error) = root_cause.downcast_ref::<ErrorList>() {
            for error in &error.errors {
                self.report(error);
            }
        } else {
            self.map
                .borrow_mut()
                .entry(Cow::Borrowed("{}"))
                .or_default()
                .add(Cow::Owned(hide_unstable_details(&format!("{error}"))));
        }
    }
}

#[derive(Default, Debug, Serialize)]
struct ErrorReportEntry {
    count: u64,
    #[serde(skip_serializing_if = "String::is_empty")]
    sample_message: String,
}

impl ErrorReportEntry {
    fn add(&mut self, message: Cow<str>) {
        if self.count == 0 {
            self.sample_message = message.into_owned();
        }
        self.count += 1;
    }
}

/// Reporter for fatal errors that will cause bindings generation to fail.
pub trait ReportFatalError {
    /// Reports a fatal error that will cause bindings generation to fail.
    ///
    /// These errors should be issued only in response to misusage of Crubit
    /// itself, such as incorrect use of Crubit-specific annotations.
    fn report(&self, msg: &str);
}

/// A collection of errors that should cause bindings generation to fail.
#[derive(Default)]
pub struct FatalErrors {
    fatal_errors: std::cell::RefCell<String>,
}

impl ReportFatalError for FatalErrors {
    fn report(&self, msg: &str) {
        let mut errors = self.fatal_errors.borrow_mut();
        errors.push('\n');
        errors.push_str(msg);
    }
}

impl FatalErrors {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn take_string(&self) -> String {
        std::mem::take(&mut *self.fatal_errors.borrow_mut())
    }
}

impl Drop for FatalErrors {
    fn drop(&mut self) {
        let errors = self.fatal_errors.borrow();
        if !errors.is_empty() {
            panic!("Fatal errors in binding generation were not reported:{}", errors);
        }
    }
}

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

    use arc_anyhow::Result;

    #[gtest]
    fn anyhow_1arg_static_plain() {
        let arc_err = anyhow!("abc");
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Borrowed(_)));
        assert_eq!(err.fmt, "abc");
        assert!(matches!(err.message, Cow::Borrowed(_)));
        assert_eq!(err.message, "abc");
    }

    #[gtest]
    fn anyhow_1arg_static_fmt() {
        let some_var = "def";
        let arc_err = anyhow!("abc{some_var}");
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Borrowed(_)));
        assert_eq!(err.fmt, "abc{some_var}");
        assert!(matches!(err.message, Cow::Owned(_)));
        assert_eq!(err.message, "abcdef");
    }

    #[gtest]
    fn anyhow_1arg_dynamic() {
        let arc_err = anyhow!(format!("abc{}", "def"));
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Owned(_)));
        assert_eq!(err.fmt, "abcdef");
        assert!(matches!(err.message, Cow::Owned(_)));
        assert_eq!(err.message, "abcdef");
    }

    #[gtest]
    fn anyhow_2arg() {
        let arc_err = anyhow!("abc{}", "def");
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Borrowed(_)));
        assert_eq!(err.fmt, "abc{}");
        assert!(matches!(err.message, Cow::Borrowed(_)));
        assert_eq!(err.message, "abcdef");
    }

    #[gtest]
    fn bail_1arg_static_plain() {
        let arc_err = (|| -> arc_anyhow::Result<()> { bail!("abc") })().unwrap_err();
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Borrowed(_)));
        assert_eq!(err.fmt, "abc");
        assert!(matches!(err.message, Cow::Borrowed(_)));
        assert_eq!(err.message, "abc");
    }

    #[gtest]
    fn bail_1arg_static_fmt() {
        let some_var = "def";
        let arc_err = (|| -> arc_anyhow::Result<()> { bail!("abc{some_var}") })().unwrap_err();
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Borrowed(_)));
        assert_eq!(err.fmt, "abc{some_var}");
        assert!(matches!(err.message, Cow::Owned(_)));
        assert_eq!(err.message, "abcdef");
    }

    #[gtest]
    fn bail_1arg_dynamic() {
        let arc_err =
            (|| -> arc_anyhow::Result<()> { bail!(format!("abc{}", "def")) })().unwrap_err();
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Owned(_)));
        assert_eq!(err.fmt, "abcdef");
        assert!(matches!(err.message, Cow::Owned(_)));
        assert_eq!(err.message, "abcdef");
    }

    #[gtest]
    fn bail_2arg() {
        let arc_err = (|| -> arc_anyhow::Result<()> { bail!("abc{}", "def") })().unwrap_err();
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Borrowed(_)));
        assert_eq!(err.fmt, "abc{}");
        assert!(matches!(err.message, Cow::Borrowed(_)));
        assert_eq!(err.message, "abcdef");
    }

    #[gtest]
    fn ensure_pass() {
        let f = || {
            ensure!(true, "unused message");
            Ok(())
        };
        f().unwrap();
    }

    #[gtest]
    fn ensure_fail_1arg_static_plain() {
        let arc_err = (|| {
            ensure!(false, "abc");
            Ok(())
        })()
        .unwrap_err();
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Borrowed(_)));
        assert_eq!(err.fmt, "abc");
        assert!(matches!(err.message, Cow::Borrowed(_)));
        assert_eq!(err.message, "abc");
    }

    #[gtest]
    fn ensure_fail_1arg_static_fmt() {
        let some_var = "def";
        let arc_err = (|| {
            ensure!(false, "abc{some_var}");
            Ok(())
        })()
        .unwrap_err();
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Borrowed(_)));
        assert_eq!(err.fmt, "abc{some_var}");
        assert!(matches!(err.message, Cow::Owned(_)));
        assert_eq!(err.message, "abcdef");
    }

    #[gtest]
    fn ensure_fail_1arg_dynamic() {
        let arc_err = (|| {
            ensure!(false, format!("abc{}", "def"));
            Ok(())
        })()
        .unwrap_err();
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Owned(_)));
        assert_eq!(err.fmt, "abcdef");
        assert!(matches!(err.message, Cow::Owned(_)));
        assert_eq!(err.message, "abcdef");
    }

    #[gtest]
    fn ensure_fail_2arg() {
        let arc_err = (|| {
            ensure!(false, "abc{}", "def");
            Ok(())
        })()
        .unwrap_err();
        let err: &FormattedError = arc_err.downcast_ref().unwrap();
        assert!(matches!(err.fmt, Cow::Borrowed(_)));
        assert_eq!(err.fmt, "abc{}");
        assert!(matches!(err.message, Cow::Borrowed(_)));
        assert_eq!(err.message, "abcdef");
    }

    #[gtest]
    fn error_report() {
        let report = ErrorReport::new();
        report.report(&anyhow!("abc{}", "def"));
        report.report(&anyhow!("abc{}", "123"));
        report.report(&anyhow!("error code: {}", 65535));
        report.report(&anyhow!("no parameters"));
        report.report(&anyhow!("no parameters"));
        report.report(&anyhow!("no parameters"));
        report.report(&anyhow::Error::msg("not attributed").into());
        report.report(&anyhow!("has context from arc_anyhow::context()").context("the context"));
        report.report(
            &arc_anyhow::Context::context(
                Result::<(), _>::Err(anyhow!("has context from arc_anyhow::Context::context()")),
                "the context",
            )
            .unwrap_err(),
        );
        report.report(
            &arc_anyhow::Context::with_context(
                Result::<(), _>::Err(anyhow!(
                    "has context from arc_anyhow::Context::with_context()"
                )),
                || "the context",
            )
            .unwrap_err(),
        );
        report.report(
            &anyhow!("has three layers of context")
                .context("context 1")
                .context("context 2")
                .context("context 3"),
        );

        expect_eq!(
            serde_json::from_str::<serde_json::Value>(&report.to_json_string()).unwrap(),
            serde_json::json!({
              "abc{}": {
                "count": 2,
                "sample_message": "abcdef"
              },
              "error code: {}": {
                "count": 1,
                "sample_message": "error code: 65535"
              },
              "has context from arc_anyhow::Context::context()": {
                "count": 1
              },
              "has context from arc_anyhow::Context::with_context()": {
                "count": 1
              },
              "has context from arc_anyhow::context()": {
                "count": 1
              },
              "has three layers of context": {
                "count": 1
              },
              "no parameters": {
                "count": 3
              },
              "{}": {
                "count": 1,
                "sample_message": "not attributed"
              }
            }),
        );
    }

    #[gtest]
    fn test_error_list_elements_are_reported() {
        let report = ErrorReport::new();
        report.report(&arc_anyhow::Error::from(ErrorList::from(vec![
            anyhow!("abc{}", "def"),
            anyhow!("hijk"),
        ])));
        expect_eq!(
            serde_json::from_str::<serde_json::Value>(&report.to_json_string()).unwrap(),
            serde_json::json!({
              "abc{}": {
                "count": 1,
                "sample_message": "abcdef"
              },
              "hijk": {
                "count": 1
              }
            }),
        );
    }
}
