//! Array-backed append-only vector type.
// TODO(tarcieri): use `core` impl of `ArrayVec`
// See: https://github.com/rust-lang/rfcs/pull/2990

use crate::{ErrorKind, Result};

/// Array-backed append-only vector type.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub(crate) struct ArrayVec<T, const N: usize> {
    /// Elements of the set.
    elements: [Option<T>; N],

    /// Last populated element.
    length: usize,
}

impl<T, const N: usize> ArrayVec<T, N> {
    /// Create a new [`ArrayVec`].
    pub fn new() -> Self {
        Self {
            elements: [(); N].map(|_| None),
            length: 0,
        }
    }

    /// Add an element to this [`ArrayVec`].
    ///
    /// Items MUST be added in lexicographical order according to the `Ord`
    /// impl on `T`.
    pub fn add(&mut self, element: T) -> Result<()> {
        match self.length.checked_add(1) {
            Some(n) if n <= N => {
                self.elements[self.length] = Some(element);
                self.length = n;
                Ok(())
            }
            _ => Err(ErrorKind::Overlength.into()),
        }
    }

    /// Get an element from this [`ArrayVec`].
    pub fn get(&self, index: usize) -> Option<&T> {
        match self.elements.get(index) {
            Some(Some(ref item)) => Some(item),
            _ => None,
        }
    }

    /// Iterate over the elements in this [`ArrayVec`].
    pub fn iter(&self) -> Iter<'_, T> {
        Iter::new(&self.elements)
    }

    /// Is this [`ArrayVec`] empty?
    pub fn is_empty(&self) -> bool {
        self.length == 0
    }

    /// Get the number of elements in this [`ArrayVec`].
    pub fn len(&self) -> usize {
        self.length
    }

    /// Get the last item from this [`ArrayVec`].
    pub fn last(&self) -> Option<&T> {
        self.length.checked_sub(1).and_then(|n| self.get(n))
    }

    /// Extract the inner array.
    pub fn into_array(self) -> [Option<T>; N] {
        self.elements
    }
}

impl<T, const N: usize> AsRef<[Option<T>]> for ArrayVec<T, N> {
    fn as_ref(&self) -> &[Option<T>] {
        &self.elements[..self.length]
    }
}

impl<T, const N: usize> AsMut<[Option<T>]> for ArrayVec<T, N> {
    fn as_mut(&mut self) -> &mut [Option<T>] {
        &mut self.elements[..self.length]
    }
}

impl<T, const N: usize> Default for ArrayVec<T, N> {
    fn default() -> Self {
        Self::new()
    }
}

/// Iterator over the elements of an [`ArrayVec`].
#[derive(Clone, Debug)]
pub struct Iter<'a, T> {
    /// Decoder which iterates over the elements of the message.
    elements: &'a [Option<T>],

    /// Position within the iterator.
    position: usize,
}

impl<'a, T> Iter<'a, T> {
    pub(crate) fn new(elements: &'a [Option<T>]) -> Self {
        Self {
            elements,
            position: 0,
        }
    }
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        match self.elements.get(self.position) {
            Some(Some(res)) => {
                self.position = self.position.checked_add(1)?;
                Some(res)
            }
            _ => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.elements.len().saturating_sub(self.position);
        (len, Some(len))
    }
}

impl<'a, T> ExactSizeIterator for Iter<'a, T> {}

#[cfg(test)]
mod tests {
    use super::ArrayVec;
    use crate::ErrorKind;

    #[test]
    fn add() {
        let mut vec = ArrayVec::<u8, 3>::new();
        vec.add(1).unwrap();
        vec.add(2).unwrap();
        vec.add(3).unwrap();

        assert_eq!(vec.add(4).err().unwrap(), ErrorKind::Overlength.into());
        assert_eq!(vec.len(), 3);
    }
}
