//! The various iterators this crate provides.
//!
//! These iterators are not a very stable interface and you really should
//! avoid considering them to be concrete types.  A lot of the iterators in
//! this crate use `impl Iterator` for this reason but restrictions in the
//! language don't allow this to be used in all places on the versions of
//! rust this crate wants to compile for.
use std::marker::PhantomData;
use std::ops::{Index, Range};

use crate::{Change, ChangeTag, DiffOp, DiffTag};

/// Iterator for [`DiffOp::iter_changes`].
pub struct ChangesIter<'lookup, Old: ?Sized, New: ?Sized, T> {
    old: &'lookup Old,
    new: &'lookup New,
    old_range: Range<usize>,
    new_range: Range<usize>,
    old_index: usize,
    new_index: usize,
    old_i: usize,
    new_i: usize,
    tag: DiffTag,
    _marker: PhantomData<T>,
}

impl<'lookup, Old, New, T> ChangesIter<'lookup, Old, New, T>
where
    Old: Index<usize, Output = T> + ?Sized,
    New: Index<usize, Output = T> + ?Sized,
{
    pub(crate) fn new(old: &'lookup Old, new: &'lookup New, op: DiffOp) -> Self {
        let (tag, old_range, new_range) = op.as_tag_tuple();
        let old_index = old_range.start;
        let new_index = new_range.start;
        let old_i = old_range.start;
        let new_i = new_range.start;
        ChangesIter {
            old,
            new,
            old_range,
            new_range,
            old_index,
            new_index,
            old_i,
            new_i,
            tag,
            _marker: PhantomData,
        }
    }
}

impl<'lookup, Old, New, T> Iterator for ChangesIter<'lookup, Old, New, T>
where
    Old: Index<usize, Output = T> + ?Sized,
    New: Index<usize, Output = T> + ?Sized,
    T: Clone,
{
    type Item = Change<T>;

    fn next(&mut self) -> Option<Self::Item> {
        match self.tag {
            DiffTag::Equal => {
                if self.old_i < self.old_range.end {
                    let value = self.old[self.old_i].clone();
                    self.old_i += 1;
                    self.old_index += 1;
                    self.new_index += 1;
                    Some(Change {
                        tag: ChangeTag::Equal,
                        old_index: Some(self.old_index - 1),
                        new_index: Some(self.new_index - 1),
                        value,
                    })
                } else {
                    None
                }
            }
            DiffTag::Delete => {
                if self.old_i < self.old_range.end {
                    let value = self.old[self.old_i].clone();
                    self.old_i += 1;
                    self.old_index += 1;
                    Some(Change {
                        tag: ChangeTag::Delete,
                        old_index: Some(self.old_index - 1),
                        new_index: None,
                        value,
                    })
                } else {
                    None
                }
            }
            DiffTag::Insert => {
                if self.new_i < self.new_range.end {
                    let value = self.new[self.new_i].clone();
                    self.new_i += 1;
                    self.new_index += 1;
                    Some(Change {
                        tag: ChangeTag::Insert,
                        old_index: None,
                        new_index: Some(self.new_index - 1),
                        value,
                    })
                } else {
                    None
                }
            }
            DiffTag::Replace => {
                if self.old_i < self.old_range.end {
                    let value = self.old[self.old_i].clone();
                    self.old_i += 1;
                    self.old_index += 1;
                    Some(Change {
                        tag: ChangeTag::Delete,
                        old_index: Some(self.old_index - 1),
                        new_index: None,
                        value,
                    })
                } else if self.new_i < self.new_range.end {
                    let value = self.new[self.new_i].clone();
                    self.new_i += 1;
                    self.new_index += 1;
                    Some(Change {
                        tag: ChangeTag::Insert,
                        old_index: None,
                        new_index: Some(self.new_index - 1),
                        value,
                    })
                } else {
                    None
                }
            }
        }
    }
}

#[cfg(feature = "text")]
mod text {
    use super::*;

    /// Iterator for [`TextDiff::iter_all_changes`](crate::TextDiff::iter_all_changes).
    pub struct AllChangesIter<'slf, 'data, T: ?Sized> {
        old: &'slf [&'data T],
        new: &'slf [&'data T],
        ops: &'slf [DiffOp],
        current_iter: Option<ChangesIter<'slf, [&'data T], [&'data T], &'data T>>,
    }

    impl<'slf, 'data, T> AllChangesIter<'slf, 'data, T>
    where
        T: 'data + ?Sized + PartialEq,
    {
        pub(crate) fn new(
            old: &'slf [&'data T],
            new: &'slf [&'data T],
            ops: &'slf [DiffOp],
        ) -> Self {
            AllChangesIter {
                old,
                new,
                ops,
                current_iter: None,
            }
        }
    }

    impl<'slf, 'data, T> Iterator for AllChangesIter<'slf, 'data, T>
    where
        T: PartialEq + 'data + ?Sized,
        'data: 'slf,
    {
        type Item = Change<&'data T>;

        fn next(&mut self) -> Option<Self::Item> {
            loop {
                if let Some(ref mut iter) = self.current_iter {
                    if let Some(rv) = iter.next() {
                        return Some(rv);
                    }
                    self.current_iter.take();
                }
                if let Some((&first, rest)) = self.ops.split_first() {
                    self.current_iter = Some(ChangesIter::new(self.old, self.new, first));
                    self.ops = rest;
                } else {
                    return None;
                }
            }
        }
    }
}

#[cfg(feature = "text")]
pub use self::text::*;
