use super::error::{ContextError, ErrorImpl};
use super::{Report, WrapErr};
use core::fmt::{self, Debug, Display, Write};

use std::error::Error as StdError;

use crate::{Diagnostic, LabeledSpan};

mod ext {
    use super::*;

    pub trait Diag {
        #[cfg_attr(track_caller, track_caller)]
        fn ext_report<D>(self, msg: D) -> Report
        where
            D: Display + Send + Sync + 'static;
    }

    impl<E> Diag for E
    where
        E: Diagnostic + Send + Sync + 'static,
    {
        fn ext_report<D>(self, msg: D) -> Report
        where
            D: Display + Send + Sync + 'static,
        {
            Report::from_msg(msg, self)
        }
    }

    impl Diag for Report {
        fn ext_report<D>(self, msg: D) -> Report
        where
            D: Display + Send + Sync + 'static,
        {
            self.wrap_err(msg)
        }
    }
}

impl<T, E> WrapErr<T, E> for Result<T, E>
where
    E: ext::Diag + Send + Sync + 'static,
{
    fn wrap_err<D>(self, msg: D) -> Result<T, Report>
    where
        D: Display + Send + Sync + 'static,
    {
        match self {
            Ok(t) => Ok(t),
            Err(e) => Err(e.ext_report(msg)),
        }
    }

    fn wrap_err_with<D, F>(self, msg: F) -> Result<T, Report>
    where
        D: Display + Send + Sync + 'static,
        F: FnOnce() -> D,
    {
        match self {
            Ok(t) => Ok(t),
            Err(e) => Err(e.ext_report(msg())),
        }
    }

    fn context<D>(self, msg: D) -> Result<T, Report>
    where
        D: Display + Send + Sync + 'static,
    {
        self.wrap_err(msg)
    }

    fn with_context<D, F>(self, msg: F) -> Result<T, Report>
    where
        D: Display + Send + Sync + 'static,
        F: FnOnce() -> D,
    {
        self.wrap_err_with(msg)
    }
}

impl<D, E> Debug for ContextError<D, E>
where
    D: Display,
    E: Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Error")
            .field("msg", &Quoted(&self.msg))
            .field("source", &self.error)
            .finish()
    }
}

impl<D, E> Display for ContextError<D, E>
where
    D: Display,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        Display::fmt(&self.msg, f)
    }
}

impl<D, E> StdError for ContextError<D, E>
where
    D: Display,
    E: StdError + 'static,
{
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        Some(&self.error)
    }
}

impl<D> StdError for ContextError<D, Report>
where
    D: Display,
{
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        unsafe { Some(ErrorImpl::error(self.error.inner.by_ref())) }
    }
}

impl<D, E> Diagnostic for ContextError<D, E>
where
    D: Display,
    E: Diagnostic + 'static,
{
    fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
        self.error.code()
    }

    fn severity(&self) -> Option<crate::Severity> {
        self.error.severity()
    }

    fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
        self.error.help()
    }

    fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
        self.error.url()
    }

    fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> {
        self.error.labels()
    }

    fn source_code(&self) -> Option<&dyn crate::SourceCode> {
        self.error.source_code()
    }

    fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
        self.error.related()
    }
}

impl<D> Diagnostic for ContextError<D, Report>
where
    D: Display,
{
    fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
        unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).code() }
    }

    fn severity(&self) -> Option<crate::Severity> {
        unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).severity() }
    }

    fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
        unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).help() }
    }

    fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
        unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).url() }
    }

    fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> {
        unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).labels() }
    }

    fn source_code(&self) -> Option<&dyn crate::SourceCode> {
        self.error.source_code()
    }

    fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
        self.error.related()
    }
}

struct Quoted<D>(D);

impl<D> Debug for Quoted<D>
where
    D: Display,
{
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        formatter.write_char('"')?;
        Quoted(&mut *formatter).write_fmt(format_args!("{}", self.0))?;
        formatter.write_char('"')?;
        Ok(())
    }
}

impl Write for Quoted<&mut fmt::Formatter<'_>> {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        Display::fmt(&s.escape_debug(), self.0)
    }
}

pub(crate) mod private {
    use super::*;

    pub trait Sealed {}

    impl<T, E> Sealed for Result<T, E> where E: ext::Diag {}
    impl<T> Sealed for Option<T> {}
}
