use std::cmp::Ordering;
use std::fmt::Debug;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;

/// A blueprint for crash test dummy instances that monitor particular events.
/// Some instances may be configured to panic at some point.
/// Events are `clone`, `drop` or some anonymous `query`.
///
/// Crash test dummies are identified and ordered by an id, so they can be used
/// as keys in a BTreeMap.
#[derive(Debug)]
pub(crate) struct CrashTestDummy {
    pub id: usize,
    cloned: AtomicUsize,
    dropped: AtomicUsize,
    queried: AtomicUsize,
}

impl CrashTestDummy {
    /// Creates a crash test dummy design. The `id` determines order and equality of instances.
    pub(crate) fn new(id: usize) -> CrashTestDummy {
        CrashTestDummy {
            id,
            cloned: AtomicUsize::new(0),
            dropped: AtomicUsize::new(0),
            queried: AtomicUsize::new(0),
        }
    }

    /// Creates an instance of a crash test dummy that records what events it experiences
    /// and optionally panics.
    pub(crate) fn spawn(&self, panic: Panic) -> Instance<'_> {
        Instance { origin: self, panic }
    }

    /// Returns how many times instances of the dummy have been cloned.
    #[allow(unused)]
    pub(crate) fn cloned(&self) -> usize {
        self.cloned.load(SeqCst)
    }

    /// Returns how many times instances of the dummy have been dropped.
    pub(crate) fn dropped(&self) -> usize {
        self.dropped.load(SeqCst)
    }

    /// Returns how many times instances of the dummy have had their `query` member invoked.
    #[allow(unused)]
    pub(crate) fn queried(&self) -> usize {
        self.queried.load(SeqCst)
    }
}

#[derive(Debug)]
pub(crate) struct Instance<'a> {
    origin: &'a CrashTestDummy,
    panic: Panic,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum Panic {
    Never,
    InClone,
    InDrop,
    InQuery,
}

impl Instance<'_> {
    pub(crate) fn id(&self) -> usize {
        self.origin.id
    }

    /// Some anonymous query, the result of which is already given.
    #[allow(unused)]
    pub(crate) fn query<R>(&self, result: R) -> R {
        self.origin.queried.fetch_add(1, SeqCst);
        if self.panic == Panic::InQuery {
            panic!("panic in `query`");
        }
        result
    }
}

impl Clone for Instance<'_> {
    fn clone(&self) -> Self {
        self.origin.cloned.fetch_add(1, SeqCst);
        if self.panic == Panic::InClone {
            panic!("panic in `clone`");
        }
        Self { origin: self.origin, panic: Panic::Never }
    }
}

impl Drop for Instance<'_> {
    fn drop(&mut self) {
        self.origin.dropped.fetch_add(1, SeqCst);
        if self.panic == Panic::InDrop {
            panic!("panic in `drop`");
        }
    }
}

impl PartialOrd for Instance<'_> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.id().partial_cmp(&other.id())
    }
}

impl Ord for Instance<'_> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.id().cmp(&other.id())
    }
}

impl PartialEq for Instance<'_> {
    fn eq(&self, other: &Self) -> bool {
        self.id().eq(&other.id())
    }
}

impl Eq for Instance<'_> {}
