use crate::fmt::Debug;
use std::cmp::Ordering;
use std::sync::atomic::{AtomicUsize, 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. The implementation intentionally uses does not rely
/// on anything defined in the crate, apart from the `Debug` trait.
#[derive(Debug)]
pub struct CrashTestDummy {
    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 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 fn spawn(&self, panic: Panic) -> Instance<'_> {
        Instance { origin: self, panic }
    }

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

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

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

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

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

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

    /// Some anonymous query, the result of which is already given.
    pub 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<'_> {}
