#[cfg(backtrace)]
pub(crate) use std::backtrace::{Backtrace, BacktraceStatus};

#[cfg(all(not(backtrace), feature = "backtrace"))]
pub(crate) use self::capture::{Backtrace, BacktraceStatus};

#[cfg(not(any(backtrace, feature = "backtrace")))]
pub(crate) enum Backtrace {}

#[cfg(backtrace)]
macro_rules! impl_backtrace {
    () => {
        std::backtrace::Backtrace
    };
}

#[cfg(all(not(backtrace), feature = "backtrace"))]
macro_rules! impl_backtrace {
    () => {
        impl core::fmt::Debug + core::fmt::Display
    };
}

#[cfg(any(backtrace, feature = "backtrace"))]
macro_rules! backtrace {
    () => {
        Some(crate::backtrace::Backtrace::capture())
    };
}

#[cfg(not(any(backtrace, feature = "backtrace")))]
macro_rules! backtrace {
    () => {
        None
    };
}

#[cfg(backtrace)]
macro_rules! backtrace_if_absent {
    ($err:expr) => {
        match $err.backtrace() {
            Some(_) => None,
            None => backtrace!(),
        }
    };
}

#[cfg(all(feature = "std", not(backtrace), feature = "backtrace"))]
macro_rules! backtrace_if_absent {
    ($err:expr) => {
        backtrace!()
    };
}

#[cfg(all(feature = "std", not(backtrace), not(feature = "backtrace")))]
macro_rules! backtrace_if_absent {
    ($err:expr) => {
        None
    };
}

#[cfg(all(not(backtrace), feature = "backtrace"))]
mod capture {
    use backtrace::{BacktraceFmt, BytesOrWideString, Frame, PrintFmt, SymbolName};
    use core::cell::UnsafeCell;
    use core::fmt::{self, Debug, Display};
    use core::sync::atomic::{AtomicUsize, Ordering};
    use std::borrow::Cow;
    use std::env;
    use std::path::{self, Path, PathBuf};
    use std::sync::Once;

    pub(crate) struct Backtrace {
        inner: Inner,
    }

    pub(crate) enum BacktraceStatus {
        Unsupported,
        Disabled,
        Captured,
    }

    enum Inner {
        Unsupported,
        Disabled,
        Captured(LazilyResolvedCapture),
    }

    struct Capture {
        actual_start: usize,
        resolved: bool,
        frames: Vec<BacktraceFrame>,
    }

    struct BacktraceFrame {
        frame: Frame,
        symbols: Vec<BacktraceSymbol>,
    }

    struct BacktraceSymbol {
        name: Option<Vec<u8>>,
        filename: Option<BytesOrWide>,
        lineno: Option<u32>,
        colno: Option<u32>,
    }

    enum BytesOrWide {
        Bytes(Vec<u8>),
        Wide(Vec<u16>),
    }

    impl Debug for Backtrace {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            let capture = match &self.inner {
                Inner::Unsupported => return fmt.write_str("<unsupported>"),
                Inner::Disabled => return fmt.write_str("<disabled>"),
                Inner::Captured(c) => c.force(),
            };

            let frames = &capture.frames[capture.actual_start..];

            write!(fmt, "Backtrace ")?;

            let mut dbg = fmt.debug_list();

            for frame in frames {
                if frame.frame.ip().is_null() {
                    continue;
                }

                dbg.entries(&frame.symbols);
            }

            dbg.finish()
        }
    }

    impl Debug for BacktraceFrame {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            let mut dbg = fmt.debug_list();
            dbg.entries(&self.symbols);
            dbg.finish()
        }
    }

    impl Debug for BacktraceSymbol {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            write!(fmt, "{{ ")?;

            if let Some(fn_name) = self.name.as_ref().map(|b| SymbolName::new(b)) {
                write!(fmt, "fn: \"{:#}\"", fn_name)?;
            } else {
                write!(fmt, "fn: <unknown>")?;
            }

            if let Some(fname) = self.filename.as_ref() {
                write!(fmt, ", file: \"{:?}\"", fname)?;
            }

            if let Some(line) = self.lineno {
                write!(fmt, ", line: {:?}", line)?;
            }

            write!(fmt, " }}")
        }
    }

    impl Debug for BytesOrWide {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            output_filename(
                fmt,
                match self {
                    BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
                    BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
                },
                PrintFmt::Short,
                env::current_dir().as_ref().ok(),
            )
        }
    }

    impl Backtrace {
        fn enabled() -> bool {
            static ENABLED: AtomicUsize = AtomicUsize::new(0);
            match ENABLED.load(Ordering::Relaxed) {
                0 => {}
                1 => return false,
                _ => return true,
            }
            let enabled = match env::var_os("RUST_LIB_BACKTRACE") {
                Some(s) => s != "0",
                None => match env::var_os("RUST_BACKTRACE") {
                    Some(s) => s != "0",
                    None => false,
                },
            };
            ENABLED.store(enabled as usize + 1, Ordering::Relaxed);
            enabled
        }

        #[inline(never)] // want to make sure there's a frame here to remove
        pub(crate) fn capture() -> Backtrace {
            if Backtrace::enabled() {
                Backtrace::create(Backtrace::capture as usize)
            } else {
                let inner = Inner::Disabled;
                Backtrace { inner }
            }
        }

        // Capture a backtrace which starts just before the function addressed
        // by `ip`
        fn create(ip: usize) -> Backtrace {
            let mut frames = Vec::new();
            let mut actual_start = None;
            backtrace::trace(|frame| {
                frames.push(BacktraceFrame {
                    frame: frame.clone(),
                    symbols: Vec::new(),
                });
                if frame.symbol_address() as usize == ip && actual_start.is_none() {
                    actual_start = Some(frames.len() + 1);
                }
                true
            });

            // If no frames came out assume that this is an unsupported platform
            // since `backtrace` doesn't provide a way of learning this right
            // now, and this should be a good enough approximation.
            let inner = if frames.is_empty() {
                Inner::Unsupported
            } else {
                Inner::Captured(LazilyResolvedCapture::new(Capture {
                    actual_start: actual_start.unwrap_or(0),
                    frames,
                    resolved: false,
                }))
            };

            Backtrace { inner }
        }

        pub(crate) fn status(&self) -> BacktraceStatus {
            match self.inner {
                Inner::Unsupported => BacktraceStatus::Unsupported,
                Inner::Disabled => BacktraceStatus::Disabled,
                Inner::Captured(_) => BacktraceStatus::Captured,
            }
        }
    }

    impl Display for Backtrace {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            let capture = match &self.inner {
                Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
                Inner::Disabled => return fmt.write_str("disabled backtrace"),
                Inner::Captured(c) => c.force(),
            };

            let full = fmt.alternate();
            let (frames, style) = if full {
                (&capture.frames[..], PrintFmt::Full)
            } else {
                (&capture.frames[capture.actual_start..], PrintFmt::Short)
            };

            // When printing paths we try to strip the cwd if it exists,
            // otherwise we just print the path as-is. Note that we also only do
            // this for the short format, because if it's full we presumably
            // want to print everything.
            let cwd = env::current_dir();
            let mut print_path = move |fmt: &mut fmt::Formatter, path: BytesOrWideString| {
                output_filename(fmt, path, style, cwd.as_ref().ok())
            };

            let mut f = BacktraceFmt::new(fmt, style, &mut print_path);
            f.add_context()?;
            for frame in frames {
                let mut f = f.frame();
                if frame.symbols.is_empty() {
                    f.print_raw(frame.frame.ip(), None, None, None)?;
                } else {
                    for symbol in frame.symbols.iter() {
                        f.print_raw_with_column(
                            frame.frame.ip(),
                            symbol.name.as_ref().map(|b| SymbolName::new(b)),
                            symbol.filename.as_ref().map(|b| match b {
                                BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
                                BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
                            }),
                            symbol.lineno,
                            symbol.colno,
                        )?;
                    }
                }
            }
            f.finish()?;
            Ok(())
        }
    }

    struct LazilyResolvedCapture {
        sync: Once,
        capture: UnsafeCell<Capture>,
    }

    impl LazilyResolvedCapture {
        fn new(capture: Capture) -> Self {
            LazilyResolvedCapture {
                sync: Once::new(),
                capture: UnsafeCell::new(capture),
            }
        }

        fn force(&self) -> &Capture {
            self.sync.call_once(|| {
                // Safety: This exclusive reference can't overlap with any
                // others. `Once` guarantees callers will block until this
                // closure returns. `Once` also guarantees only a single caller
                // will enter this closure.
                unsafe { &mut *self.capture.get() }.resolve();
            });

            // Safety: This shared reference can't overlap with the exclusive
            // reference above.
            unsafe { &*self.capture.get() }
        }
    }

    // Safety: Access to the inner value is synchronized using a thread-safe
    // `Once`. So long as `Capture` is `Sync`, `LazilyResolvedCapture` is too
    unsafe impl Sync for LazilyResolvedCapture where Capture: Sync {}

    impl Capture {
        fn resolve(&mut self) {
            // If we're already resolved, nothing to do!
            if self.resolved {
                return;
            }
            self.resolved = true;

            for frame in self.frames.iter_mut() {
                let symbols = &mut frame.symbols;
                let frame = &frame.frame;
                backtrace::resolve_frame(frame, |symbol| {
                    symbols.push(BacktraceSymbol {
                        name: symbol.name().map(|m| m.as_bytes().to_vec()),
                        filename: symbol.filename_raw().map(|b| match b {
                            BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()),
                            BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()),
                        }),
                        lineno: symbol.lineno(),
                        colno: symbol.colno(),
                    });
                });
            }
        }
    }

    // Prints the filename of the backtrace frame.
    fn output_filename(
        fmt: &mut fmt::Formatter,
        bows: BytesOrWideString,
        print_fmt: PrintFmt,
        cwd: Option<&PathBuf>,
    ) -> fmt::Result {
        let file: Cow<Path> = match bows {
            #[cfg(unix)]
            BytesOrWideString::Bytes(bytes) => {
                use std::os::unix::ffi::OsStrExt;
                Path::new(std::ffi::OsStr::from_bytes(bytes)).into()
            }
            #[cfg(not(unix))]
            BytesOrWideString::Bytes(bytes) => {
                Path::new(std::str::from_utf8(bytes).unwrap_or("<unknown>")).into()
            }
            #[cfg(windows)]
            BytesOrWideString::Wide(wide) => {
                use std::os::windows::ffi::OsStringExt;
                Cow::Owned(std::ffi::OsString::from_wide(wide).into())
            }
            #[cfg(not(windows))]
            BytesOrWideString::Wide(_wide) => Path::new("<unknown>").into(),
        };
        if print_fmt == PrintFmt::Short && file.is_absolute() {
            if let Some(cwd) = cwd {
                if let Ok(stripped) = file.strip_prefix(&cwd) {
                    if let Some(s) = stripped.to_str() {
                        return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s);
                    }
                }
            }
        }
        Display::fmt(&file.display(), fmt)
    }
}

fn _assert_send_sync() {
    fn _assert<T: Send + Sync>() {}
    _assert::<Backtrace>();
}
