mod array_chunks;
mod by_ref_sized;
mod chain;
mod cloned;
mod copied;
mod cycle;
mod enumerate;
mod filter;
mod filter_map;
mod flat_map;
mod flatten;
mod fuse;
mod inspect;
mod intersperse;
mod map;
mod peekable;
mod scan;
mod skip;
mod skip_while;
mod step_by;
mod take;
mod take_while;
mod zip;

use core::cell::Cell;

/// An iterator that panics whenever `next` or next_back` is called
/// after `None` has already been returned. This does not violate
/// `Iterator`'s contract. Used to test that iterator adapters don't
/// poll their inner iterators after exhausting them.
pub struct NonFused<I> {
    iter: I,
    done: bool,
}

impl<I> NonFused<I> {
    pub fn new(iter: I) -> Self {
        Self { iter, done: false }
    }
}

impl<I> Iterator for NonFused<I>
where
    I: Iterator,
{
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        assert!(!self.done, "this iterator has already returned None");
        self.iter.next().or_else(|| {
            self.done = true;
            None
        })
    }
}

impl<I> DoubleEndedIterator for NonFused<I>
where
    I: DoubleEndedIterator,
{
    fn next_back(&mut self) -> Option<Self::Item> {
        assert!(!self.done, "this iterator has already returned None");
        self.iter.next_back().or_else(|| {
            self.done = true;
            None
        })
    }
}

/// An iterator wrapper that panics whenever `next` or `next_back` is called
/// after `None` has been returned.
pub struct Unfuse<I> {
    iter: I,
    exhausted: bool,
}

impl<I> Unfuse<I> {
    pub fn new<T>(iter: T) -> Self
    where
        T: IntoIterator<IntoIter = I>,
    {
        Self { iter: iter.into_iter(), exhausted: false }
    }
}

impl<I> Iterator for Unfuse<I>
where
    I: Iterator,
{
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        assert!(!self.exhausted);
        let next = self.iter.next();
        self.exhausted = next.is_none();
        next
    }
}

impl<I> DoubleEndedIterator for Unfuse<I>
where
    I: DoubleEndedIterator,
{
    fn next_back(&mut self) -> Option<Self::Item> {
        assert!(!self.exhausted);
        let next = self.iter.next_back();
        self.exhausted = next.is_none();
        next
    }
}

pub struct Toggle {
    is_empty: bool,
}

impl Iterator for Toggle {
    type Item = ();

    // alternates between `None` and `Some(())`
    fn next(&mut self) -> Option<Self::Item> {
        if self.is_empty {
            self.is_empty = false;
            None
        } else {
            self.is_empty = true;
            Some(())
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        if self.is_empty { (0, Some(0)) } else { (1, Some(1)) }
    }
}

impl DoubleEndedIterator for Toggle {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.next()
    }
}

/// This is an iterator that follows the Iterator contract,
/// but it is not fused. After having returned None once, it will start
/// producing elements if .next() is called again.
pub struct CycleIter<'a, T> {
    index: usize,
    data: &'a [T],
}

impl<'a, T> CycleIter<'a, T> {
    pub fn new(data: &'a [T]) -> Self {
        Self { index: 0, data }
    }
}

impl<'a, T> Iterator for CycleIter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<Self::Item> {
        let elt = self.data.get(self.index);
        self.index += 1;
        self.index %= 1 + self.data.len();
        elt
    }
}

#[derive(Debug)]
struct CountClone(Cell<i32>);

impl CountClone {
    pub fn new() -> Self {
        Self(Cell::new(0))
    }
}

impl PartialEq<i32> for CountClone {
    fn eq(&self, rhs: &i32) -> bool {
        self.0.get() == *rhs
    }
}

impl Clone for CountClone {
    fn clone(&self) -> Self {
        let ret = CountClone(self.0.clone());
        let n = self.0.get();
        self.0.set(n + 1);
        ret
    }
}

#[derive(Debug, Clone)]
struct CountDrop<'a> {
    dropped: bool,
    count: &'a Cell<usize>,
}

impl<'a> CountDrop<'a> {
    pub fn new(count: &'a Cell<usize>) -> Self {
        Self { dropped: false, count }
    }
}

impl Drop for CountDrop<'_> {
    fn drop(&mut self) {
        if self.dropped {
            panic!("double drop");
        }
        self.dropped = true;
        self.count.set(self.count.get() + 1);
    }
}
