//! # cov-mark
//!
//! This library at its core provides two macros, [`hit!`] and [`check!`],
//! which can be used to verify that a certain test exercises a certain code
//! path.
//!
//! Here's a short example:
//!
//! ```
//! fn parse_date(s: &str) -> Option<(u32, u32, u32)> {
//!     if 10 != s.len() {
//!         // By using `cov_mark::hit!`
//!         // we signal which test exercises this code.
//!         cov_mark::hit!(short_date);
//!         return None;
//!     }
//!
//!     if "-" != &s[4..5] || "-" != &s[7..8] {
//!         cov_mark::hit!(bad_dashes);
//!         return None;
//!     }
//!     // ...
//! #    unimplemented!()
//! }
//!
//! #[test]
//! fn test_parse_date() {
//!     {
//!         // `cov_mark::check!` creates a guard object
//!         // that verifies that by the end of the scope we've
//!         // executed the corresponding `cov_mark::hit`.
//!         cov_mark::check!(short_date);
//!         assert!(parse_date("92").is_none());
//!     }
//!
//! //  This will fail. Although the test looks like
//! //  it exercises the second condition, it does not.
//! //  The call to `check!` call catches this bug in the test.
//! //  {
//! //      cov_mark::check!(bad_dashes);
//! //      assert!(parse_date("27.2.2013").is_none());
//! //  }
//!
//!     {
//!         cov_mark::check!(bad_dashes);
//!         assert!(parse_date("27.02.2013").is_none());
//!     }
//! }
//!
//! # fn main() {}
//! ```
//!
//! Here's why coverage marks are useful:
//!
//! * Verifying that something doesn't happen for the *right* reason.
//! * Finding the test that exercises the code (grep for `check!(mark_name)`).
//! * Finding the code that the test is supposed to check (grep for `hit!(mark_name)`).
//! * Making sure that code and tests don't diverge during refactorings.
//! * (If used pervasively) Verifying that each branch has a corresponding test.
//!
//! # Limitations
//!
//! * Names of marks must be globally unique.
//!
//! # Implementation Details
//!
//! Each coverage mark is an `AtomicUsize` counter. [`hit!`] increments
//! this counter, [`check!`] returns a guard object which checks that
//! the mark was incremented.
//! Each counter is stored as a thread-local, allowing for accurate per-thread
//! counting.

#![cfg_attr(nightly_docs, deny(broken_intra_doc_links))]
#![cfg_attr(nightly_docs, feature(doc_cfg))]

/// Hit a mark with a specified name.
///
/// # Example
///
/// ```
/// fn safe_divide(dividend: u32, divisor: u32) -> u32 {
///     if divisor == 0 {
///         cov_mark::hit!(save_divide_zero);
///         return 0;
///     }
///     dividend / divisor
/// }
/// ```
#[macro_export]
macro_rules! hit {
    ($ident:ident) => {
        $crate::__rt::hit(stringify!($ident))
    };
}

/// Checks that a specified mark was hit.
///
/// # Example
///
/// ```
/// #[test]
/// fn test_safe_divide_by_zero() {
///     cov_mark::check!(save_divide_zero);
///     assert_eq!(safe_divide(92, 0), 0);
/// }
/// # fn safe_divide(dividend: u32, divisor: u32) -> u32 {
/// #     if divisor == 0 {
/// #         cov_mark::hit!(save_divide_zero);
/// #         return 0;
/// #     }
/// #     dividend / divisor
/// # }
/// ```
#[macro_export]
macro_rules! check {
    ($ident:ident) => {
        let _guard = $crate::__rt::Guard::new(stringify!($ident), None);
    };
}

/// Checks that a specified mark was hit exactly the specified number of times.
///
/// # Example
///
/// ```
/// struct CoveredDropper;
/// impl Drop for CoveredDropper {
///     fn drop(&mut self) {
///         cov_mark::hit!(covered_dropper_drops);
///     }
/// }
///
/// #[test]
/// fn drop_count_test() {
///     cov_mark::check_count!(covered_dropper_drops, 2);
///     let _covered_dropper1 = CoveredDropper;
///     let _covered_dropper2 = CoveredDropper;
/// }
/// ```
#[macro_export]
macro_rules! check_count {
    ($ident:ident, $count: literal) => {
        let _guard = $crate::__rt::Guard::new(stringify!($ident), Some($count));
    };
}

#[doc(hidden)]
#[cfg(feature = "enable")]
pub mod __rt {
    use std::{
        cell::{Cell, RefCell},
        rc::Rc,
        sync::atomic::{AtomicUsize, Ordering::Relaxed},
    };

    /// Even with
    /// https://github.com/rust-lang/rust/commit/641d3b09f41b441f2c2618de32983ad3d13ea3f8,
    /// a `thread_local` generates significantly more verbose assembly on x86
    /// than atomic, so we'll use atomic for the fast path
    static LEVEL: AtomicUsize = AtomicUsize::new(0);

    thread_local! {
        static ACTIVE: RefCell<Vec<Rc<GuardInner>>> = Default::default();
    }

    #[inline(always)]
    pub fn hit(key: &'static str) {
        if LEVEL.load(Relaxed) > 0 {
            hit_cold(key);
        }

        #[cold]
        fn hit_cold(key: &'static str) {
            ACTIVE.with(|it| it.borrow().iter().for_each(|g| g.hit(key)))
        }
    }

    struct GuardInner {
        mark: &'static str,
        hits: Cell<usize>,
        expected_hits: Option<usize>,
    }

    pub struct Guard {
        inner: Rc<GuardInner>,
    }

    impl GuardInner {
        fn hit(&self, key: &'static str) {
            if key == self.mark {
                self.hits.set(self.hits.get().saturating_add(1))
            }
        }
    }

    impl Guard {
        pub fn new(mark: &'static str, expected_hits: Option<usize>) -> Guard {
            let inner = GuardInner {
                mark,
                hits: Cell::new(0),
                expected_hits,
            };
            let inner = Rc::new(inner);
            LEVEL.fetch_add(1, Relaxed);
            ACTIVE.with(|it| it.borrow_mut().push(Rc::clone(&inner)));
            Guard { inner }
        }
    }

    impl Drop for Guard {
        fn drop(&mut self) {
            LEVEL.fetch_sub(1, Relaxed);
            let last = ACTIVE.with(|it| it.borrow_mut().pop());

            if std::thread::panicking() {
                return;
            }

            let last = last.unwrap();
            assert!(Rc::ptr_eq(&last, &self.inner));
            let hit_count = last.hits.get();
            match last.expected_hits {
                Some(hits) => assert!(
                    hit_count == hits,
                    "mark was hit {} times, expected {}",
                    hit_count,
                    hits
                ),
                None => assert!(hit_count > 0, "mark was not hit"),
            }
        }
    }
}

#[doc(hidden)]
#[cfg(not(feature = "enable"))]
pub mod __rt {
    #[inline(always)]
    pub fn hit(_: &'static str) {}

    #[non_exhaustive]
    pub struct Guard;

    impl Guard {
        pub fn new(_: &'static str, _: Option<usize>) -> Guard {
            Guard
        }
    }
}
