// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

use std::fmt::{self, Debug};
use std::iter;
use std::iter::FusedIterator;
/// Repeated scalar fields are implemented around the runtime-specific
/// `RepeatedField` struct. `RepeatedField` stores an opaque pointer to the
/// runtime-specific representation of a repeated scalar (`upb_Array*` on upb,
/// and `RepeatedField<T>*` on cpp).
use std::marker::PhantomData;

use crate::{
    __internal::runtime::{InnerRepeated, InnerRepeatedMut, RawRepeatedField},
    __internal::{Private, SealedInternal},
    AsMut, AsView, IntoMut, IntoProxied, IntoView, Message, Mut, MutProxied, Proxied, Singular,
    View,
};

/// A `repeated` field of `T`, used as the owned target for `Proxied`.
///
/// Users will generally write [`View<Repeated<T>>`](RepeatedView) or
/// [`Mut<Repeated<T>>`](RepeatedMut) to access the repeated elements
pub struct Repeated<T: Singular> {
    pub(crate) inner: InnerRepeated,
    _phantom: PhantomData<T>,
}

// SAFETY: `Repeated` is Sync because it does not implement interior mutability.
unsafe impl<T: Singular> Sync for Repeated<T> {}

// SAFETY: `Repeated` is Send because it's not bound to a specific thread e.g.
// it does not use thread-local data or similar.
unsafe impl<T: Singular> Send for Repeated<T> {}

impl<T: Singular> Repeated<T> {
    pub fn new() -> Self {
        T::repeated_new(Private)
    }

    pub(crate) fn as_mut(&mut self) -> RepeatedMut<'_, T> {
        RepeatedMut { inner: self.inner.as_mut(), _phantom: PhantomData }
    }

    pub fn as_view(&self) -> View<'_, Repeated<T>> {
        RepeatedView { raw: self.inner.raw(), _phantom: PhantomData }
    }

    #[doc(hidden)]
    pub fn inner(&self, _private: Private) -> &InnerRepeated {
        &self.inner
    }

    #[doc(hidden)]
    pub fn from_inner(_private: Private, inner: InnerRepeated) -> Self {
        Self { inner, _phantom: PhantomData }
    }
}

impl<T: Singular, I, U> IntoProxied<Repeated<T>> for I
where
    I: Iterator<Item = U>,
    U: IntoProxied<T>,
{
    fn into_proxied(self, _private: Private) -> Repeated<T> {
        let mut repeated: Repeated<T> = Repeated::new();
        repeated.as_mut().extend(self);
        repeated
    }
}

impl<T: Singular> Default for Repeated<T> {
    fn default() -> Self {
        Repeated::new()
    }
}

impl<T: Singular> Drop for Repeated<T> {
    fn drop(&mut self) {
        // SAFETY: only called once
        unsafe { T::repeated_free(Private, self) }
    }
}

impl<T: Singular> Proxied for Repeated<T> {
    type View<'msg>
        = RepeatedView<'msg, T>
    where
        Repeated<T>: 'msg;
}

impl<T: Singular> SealedInternal for Repeated<T> {}

impl<T: Singular> crate::codegen_traits::EntityType for Repeated<T> {
    type Tag = crate::codegen_traits::entity_tag::RepeatedTag;
}

impl<T: Singular> AsView for Repeated<T> {
    type Proxied = Self;

    fn as_view(&self) -> RepeatedView<'_, T> {
        self.as_view()
    }
}

impl<T: Singular> MutProxied for Repeated<T> {
    type Mut<'msg>
        = RepeatedMut<'msg, T>
    where
        Repeated<T>: 'msg;
}

impl<T: Singular> AsMut for Repeated<T> {
    type MutProxied = Self;

    fn as_mut(&mut self) -> RepeatedMut<'_, T> {
        self.as_mut()
    }
}

/// Views the elements in a `repeated` field of `T`.
#[repr(transparent)]
pub struct RepeatedView<'msg, T> {
    // This does not need to carry an arena in upb, so it can be just the raw repeated field
    raw: RawRepeatedField,
    _phantom: PhantomData<&'msg T>,
}

impl<'msg, T> Copy for RepeatedView<'msg, T> {}
impl<'msg, T> Clone for RepeatedView<'msg, T> {
    fn clone(&self) -> Self {
        *self
    }
}

unsafe impl<'msg, T> Sync for RepeatedView<'msg, T> {}
unsafe impl<'msg, T> Send for RepeatedView<'msg, T> {}

impl<'msg, T> Debug for RepeatedView<'msg, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RepeatedView").field("raw", &self.raw).finish()
    }
}

impl<'msg, T: Singular> SealedInternal for RepeatedView<'msg, T> {}

#[doc(hidden)]
impl<'msg, T> RepeatedView<'msg, T> {
    #[doc(hidden)]
    #[inline]
    pub fn as_raw(&self, _private: Private) -> RawRepeatedField {
        self.raw
    }

    /// # Safety
    /// - `inner` must be valid to read from for `'msg`
    #[doc(hidden)]
    #[inline]
    pub unsafe fn from_raw(_private: Private, raw: RawRepeatedField) -> Self {
        Self { raw, _phantom: PhantomData }
    }
}

impl<'msg, T: Singular> RepeatedView<'msg, T> {
    /// Gets the length of the repeated field.
    #[inline]
    pub fn len(&self) -> usize {
        T::repeated_len(Private, *self)
    }

    /// Returns true if the repeated field has no values.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Gets the value at `index`.
    ///
    /// Returns `None` if `index > len`.
    #[inline]
    pub fn get(self, index: usize) -> Option<View<'msg, T>> {
        if index >= self.len() {
            return None;
        }
        // SAFETY: `index` has been checked to be in-bounds
        Some(unsafe { self.get_unchecked(index) })
    }

    /// Gets the value at `index` without bounds-checking.
    ///
    /// # Safety
    /// Undefined behavior if `index >= len`
    #[inline]
    pub unsafe fn get_unchecked(self, index: usize) -> View<'msg, T> {
        // SAFETY: in-bounds as promised
        unsafe { T::repeated_get_unchecked(Private, self, index) }
    }

    /// Iterates over the values in the repeated field.
    pub fn iter(self) -> RepeatedIter<'msg, T> {
        self.into_iter()
    }

    /// Returns the first element of the repeated field, or `None` if it is empty.
    #[inline]
    pub fn first(self) -> Option<View<'msg, T>> {
        self.get(0)
    }

    /// Returns the last element of the repeated field, or `None` if it is empty.
    #[inline]
    pub fn last(self) -> Option<View<'msg, T>> {
        let len = self.len();
        if len == 0 {
            None
        } else {
            // SAFETY: len is not 0, so len - 1 is a valid index
            unsafe { Some(self.get_unchecked(len - 1)) }
        }
    }
}

impl<'msg, T: Singular> AsView for RepeatedView<'msg, T> {
    type Proxied = Repeated<T>;

    #[inline]
    fn as_view(&self) -> View<'msg, Self::Proxied> {
        *self
    }
}

impl<'msg, T: Singular> IntoView<'msg> for RepeatedView<'msg, T> {
    #[inline]
    fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
    where
        'msg: 'shorter,
    {
        RepeatedView { raw: self.raw, _phantom: PhantomData }
    }
}

impl<'msg, T: Singular> IntoProxied<Repeated<T>> for RepeatedView<'msg, T> {
    fn into_proxied(self, _private: Private) -> Repeated<T> {
        let mut repeated: Repeated<T> = Repeated::new();
        T::repeated_copy_from(Private, self, repeated.as_mut());
        repeated
    }
}

/// Mutates the elements in a `repeated` field of `T`.
pub struct RepeatedMut<'msg, T> {
    pub(crate) inner: InnerRepeatedMut<'msg>,
    _phantom: PhantomData<&'msg mut T>,
}

unsafe impl<'msg, T> Sync for RepeatedMut<'msg, T> {}

impl<'msg, T> Debug for RepeatedMut<'msg, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RepeatedMut").field("raw", &self.inner.raw).finish()
    }
}

#[doc(hidden)]
impl<'msg, T> RepeatedMut<'msg, T> {
    /// # Safety
    /// - `inner` must be valid to read and write from for `'msg`
    /// - There must be no aliasing references or mutations on the same
    ///   underlying object.
    #[doc(hidden)]
    #[inline]
    pub unsafe fn from_inner(_private: Private, inner: InnerRepeatedMut<'msg>) -> Self {
        Self { inner, _phantom: PhantomData }
    }

    #[doc(hidden)]
    #[inline]
    pub fn as_raw(&mut self, _private: Private) -> RawRepeatedField {
        self.inner.raw
    }
}

impl<'msg, T: Singular> RepeatedMut<'msg, T> {
    /// Gets the length of the repeated field.
    #[inline]
    pub fn len(&self) -> usize {
        self.as_view().len()
    }

    /// Returns true if the repeated field has no values.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Gets the value at `index`.
    ///
    /// Returns `None` if `index >= len`.
    #[inline]
    pub fn get(&self, index: usize) -> Option<View<'_, T>> {
        self.as_view().get(index)
    }

    /// Gets the value at `index`.
    ///
    /// Returns `None` if `index >= len`.
    #[inline]
    pub fn get_mut<'r>(&'r mut self, index: usize) -> Option<Mut<'msg, T>>
    where
        T: Message,
        'r: 'msg,
    {
        if index >= self.len() {
            return None;
        }
        // SAFETY: `index` has been checked to be in-bounds
        Some(unsafe { self.get_mut_unchecked(index) })
    }

    /// Gets the value at `index` without bounds-checking.
    ///
    /// # Safety
    /// Undefined behavior if `index >= len`.
    #[inline]
    pub unsafe fn get_mut_unchecked(&mut self, index: usize) -> Mut<'_, T>
    where
        T: Message,
    {
        // SAFETY: in-bounds as promised
        unsafe { T::repeated_get_mut_unchecked(Private, self.as_mut(), index) }
    }

    /// Gets the value at `index` without bounds-checking.
    ///
    /// # Safety
    /// Undefined behavior if `index >= len`.
    #[inline]
    pub unsafe fn get_unchecked(&self, index: usize) -> View<'_, T> {
        // SAFETY: in-bounds as promised
        unsafe { self.as_view().get_unchecked(index) }
    }

    /// Appends `val` to the end of the repeated field.
    #[inline]
    pub fn push(&mut self, val: impl IntoProxied<T>) {
        T::repeated_push(Private, self.as_mut(), val);
    }

    /// Appends the default message instance of T and returns a mutable reference to it.
    #[inline]
    pub fn push_default(&mut self) -> Mut<'_, T>
    where
        T: Message,
    {
        // TODO: This should be optimized on Cpp kernel by adding another thunk to expose Add().
        self.push(T::default());
        // SAFETY: we just pushed a value into the repeated field, so there is at least one element.
        unsafe { self.get_mut_unchecked(self.len() - 1) }
    }

    /// Sets the value at `index` to the value `val`.
    ///
    /// # Panics
    /// Panics if `index >= len`.
    #[inline]
    pub fn set(&mut self, index: usize, val: impl IntoProxied<T>) {
        let len = self.len();
        if index >= len {
            panic!("index {index} >= repeated len {len}");
        }
        unsafe { self.set_unchecked(index, val) }
    }

    /// Sets the value at `index` to the value `val`.
    ///
    /// # Safety
    /// Undefined behavior if `index >= len`.
    #[inline]
    pub unsafe fn set_unchecked(&mut self, index: usize, val: impl IntoProxied<T>) {
        unsafe { T::repeated_set_unchecked(Private, self.as_mut(), index, val) }
    }

    /// Iterates over the values in the repeated field.
    pub fn iter(&self) -> RepeatedIter<'_, T> {
        self.as_view().into_iter()
    }

    /// Copies from the `src` repeated field into this one.
    pub fn copy_from(&mut self, src: RepeatedView<'_, T>) {
        T::repeated_copy_from(Private, src, self.as_mut())
    }

    /// Clears the repeated field.
    pub fn clear(&mut self) {
        T::repeated_clear(Private, self.as_mut())
    }

    /// Returns the first element of the repeated field, or `None` if it is empty.
    #[inline]
    pub fn first(&self) -> Option<View<'_, T>> {
        self.as_view().first()
    }

    /// Returns the last element of the repeated field, or `None` if it is empty.
    #[inline]
    pub fn last(&self) -> Option<View<'_, T>> {
        self.as_view().last()
    }
}

impl<'msg, T: Singular> IntoProxied<Repeated<T>> for RepeatedMut<'msg, T> {
    fn into_proxied(self, _private: Private) -> Repeated<T> {
        IntoProxied::into_proxied(self.as_view(), _private)
    }
}

impl<'msg, T: Singular> SealedInternal for RepeatedMut<'msg, T> {}

impl<'msg, T: Singular> AsView for RepeatedMut<'msg, T> {
    type Proxied = Repeated<T>;

    #[inline]
    fn as_view(&self) -> RepeatedView<'_, T> {
        RepeatedView { raw: self.inner.raw, _phantom: PhantomData }
    }
}

impl<'msg, T: Singular> IntoView<'msg> for RepeatedMut<'msg, T> {
    #[inline]
    fn into_view<'shorter>(self) -> RepeatedView<'shorter, T>
    where
        'msg: 'shorter,
    {
        RepeatedView { raw: self.inner.raw, _phantom: PhantomData }
    }
}

impl<'msg, T: Singular> AsMut for RepeatedMut<'msg, T> {
    type MutProxied = Repeated<T>;

    #[inline]
    fn as_mut(&mut self) -> RepeatedMut<'_, T> {
        RepeatedMut { inner: self.inner, _phantom: PhantomData }
    }
}

impl<'msg, T: Singular> IntoMut<'msg> for RepeatedMut<'msg, T> {
    #[inline]
    fn into_mut<'shorter>(self) -> RepeatedMut<'shorter, T>
    where
        'msg: 'shorter,
    {
        RepeatedMut { inner: self.inner, _phantom: PhantomData }
    }
}

impl<'msg, T: Singular, ViewT> Extend<ViewT> for RepeatedMut<'msg, T>
where
    ViewT: IntoProxied<T>,
{
    fn extend<I: IntoIterator<Item = ViewT>>(&mut self, iter: I) {
        let iter = iter.into_iter();
        T::repeated_reserve(Private, self.as_mut(), iter.size_hint().0);
        for item in iter {
            self.push(item);
        }
    }
}

impl<T: Singular, U> std::iter::FromIterator<U> for Repeated<T>
where
    U: IntoProxied<T>,
{
    fn from_iter<I: IntoIterator<Item = U>>(iter: I) -> Self {
        let mut repeated = Repeated::new();
        repeated.as_mut().extend(iter);
        repeated
    }
}

/// An iterator over the values inside of a [`View<Repeated<T>>`](RepeatedView).
#[derive(Clone)]
pub struct RepeatedIter<'msg, T> {
    view: RepeatedView<'msg, T>,
    current_index: usize,
    end_index: usize,
}

impl<'msg, T> Debug for RepeatedIter<'msg, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RepeatedIter")
            .field("view", &self.view)
            .field("current_index", &self.current_index)
            .finish()
    }
}

impl<'msg, T: Singular> iter::Iterator for RepeatedIter<'msg, T> {
    type Item = View<'msg, T>;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.current_index >= self.end_index {
            return None;
        }
        // SAFETY: current_index < end_index <= view.len()
        let val = unsafe { self.view.get_unchecked(self.current_index) };
        self.current_index += 1;
        Some(val)
    }

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

impl<'msg, T: Singular> ExactSizeIterator for RepeatedIter<'msg, T> {
    fn len(&self) -> usize {
        self.end_index - self.current_index
    }
}

impl<'msg, T: Singular> iter::DoubleEndedIterator for RepeatedIter<'msg, T> {
    #[inline]
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.current_index >= self.end_index {
            return None;
        }
        self.end_index -= 1;
        // SAFETY: current_index <= end_index < view.len()
        Some(unsafe { self.view.get_unchecked(self.end_index) })
    }
}

impl<'msg, T: Singular> FusedIterator for RepeatedIter<'msg, T> {}

impl<'msg, T: Singular> iter::IntoIterator for RepeatedView<'msg, T> {
    type Item = View<'msg, T>;
    type IntoIter = RepeatedIter<'msg, T>;

    fn into_iter(self) -> Self::IntoIter {
        RepeatedIter { view: self, current_index: 0, end_index: self.len() }
    }
}

impl<'msg, T: Singular> iter::IntoIterator for &'_ RepeatedView<'msg, T> {
    type Item = View<'msg, T>;
    type IntoIter = RepeatedIter<'msg, T>;

    fn into_iter(self) -> Self::IntoIter {
        RepeatedIter { view: *self, current_index: 0, end_index: self.len() }
    }
}

impl<'borrow, T: Singular> iter::IntoIterator for &'borrow RepeatedMut<'_, T> {
    type Item = View<'borrow, T>;
    type IntoIter = RepeatedIter<'borrow, T>;

    fn into_iter(self) -> Self::IntoIter {
        let view = self.as_view();
        RepeatedIter { view, current_index: 0, end_index: view.len() }
    }
}

/// An iterator over the mutable values inside of a [`RepeatedMut`].
///
/// **WARNING**: This has transitioned to a **Lending Iterator**. Standard `for` loops are not
/// supported anymore. Use `while let Some(item) = iter.next()` instead.
pub struct RepeatedMutIter<'msg, T> {
    inner: InnerRepeatedMut<'msg>,
    current_index: usize,
    end_index: usize,
    _phantom: PhantomData<&'msg mut T>,
}

impl<'msg, T: Message> RepeatedMutIter<'msg, T> {
    #[inline]
    pub fn next(&mut self) -> Option<Mut<'_, T>> {
        if self.current_index >= self.end_index {
            return None;
        }
        let index = self.current_index;
        self.current_index += 1;

        // SAFETY: index is valid.
        let val = unsafe {
            let temp_repeated = RepeatedMut::from_inner(Private, self.inner);
            T::repeated_get_mut_unchecked(Private, temp_repeated, index)
        };

        Some(val)
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.end_index - self.current_index
    }

    #[inline]
    pub fn next_back(&mut self) -> Option<Mut<'_, T>> {
        if self.current_index >= self.end_index {
            return None;
        }
        self.end_index -= 1;
        let index = self.end_index;

        // SAFETY: index is guaranteed to be in bounds.
        let val = unsafe {
            let temp_repeated = RepeatedMut::from_inner(Private, self.inner);
            T::repeated_get_mut_unchecked(Private, temp_repeated, index)
        };

        Some(val)
    }
}

impl<'msg, T: Message> RepeatedMut<'msg, T> {
    /// Returns an iterator that allows modifying each value.
    pub fn iter_mut(self) -> RepeatedMutIter<'msg, T> {
        RepeatedMutIter {
            end_index: self.len(),
            inner: self.inner,
            current_index: 0,
            _phantom: PhantomData,
        }
    }

    /// Returns a mutable reference to the first element of the repeated field, or `None` if it is empty.
    #[inline]
    pub fn first_mut<'r>(&'r mut self) -> Option<Mut<'msg, T>>
    where
        'r: 'msg,
    {
        self.get_mut(0)
    }

    /// Returns a mutable reference to the last element of the repeated field, or `None` if it is empty.
    #[inline]
    pub fn last_mut<'r>(&'r mut self) -> Option<Mut<'msg, T>>
    where
        'r: 'msg,
    {
        let len = self.len();
        if len == 0 {
            None
        } else {
            // SAFETY: len is not 0, so len - 1 is valid
            Some(unsafe { self.get_mut_unchecked(len - 1) })
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use googletest::prelude::*;

    #[gtest]
    fn test_primitive_repeated() {
        macro_rules! primitive_repeated_tests {
            ($($t:ty => [$($vals:expr),* $(,)?]),* $(,)?) => {
                $({
                // Constructs a new, owned, `Repeated`, only used for tests.
                let mut r = Repeated::<$t>::new();
                let mut r = r.as_mut();
                assert_that!(r.len(), eq(0));
                assert!(r.iter().next().is_none(), "starts with empty iter");
                assert!(r.iter().next().is_none(), "starts with empty mut iter");
                assert!(r.is_empty(), "starts is_empty");

                let mut expected_len = 0usize;
                $(
                    let val: View<$t> = $vals;
                    r.push(val);
                    assert_that!(r.get(expected_len), eq(Some(val)));
                    expected_len += 1;
                    assert_that!(r.len(), eq(expected_len));

                )*
                assert_that!(r, elements_are![$(eq($vals)),*]);
                r.set(0, <$t as Default>::default());
                assert_that!(r.get(0).expect("elem 0"), eq(<$t as Default>::default()));

                r.clear();
                assert!(r.is_empty(), "is_empty after clear");
                assert!(r.iter().next().is_none(), "iter empty after clear");
                assert!(r.into_iter().next().is_none(), "mut iter empty after clear");
                })*
            }
        }
        primitive_repeated_tests!(
            u32 => [1,2,3],
            i32 => [1,2],
            f64 => [10.0, 0.1234f64],
            bool => [false, true, true, false],
        );
    }

    #[gtest]
    fn test_repeated_extend() {
        let mut r = Repeated::<i32>::new();

        r.as_mut().extend([0; 0]);
        assert_that!(r.as_mut().len(), eq(0));

        r.as_mut().extend([0, 1]);
        assert_that!(r.as_mut(), elements_are![eq(0), eq(1)]);
        let mut x = Repeated::<i32>::new();
        x.as_mut().extend([2, 3]);

        r.as_mut().extend(&x.as_mut());

        assert_that!(r.as_mut(), elements_are![eq(0), eq(1), eq(2), eq(3)]);
    }

    #[gtest]
    fn test_repeated_iter() {
        let r: Repeated<i32> = [0, 1, 2, 3].into_iter().into_proxied(Private);
        assert_that!(r.as_view(), elements_are![eq(0), eq(1), eq(2), eq(3)]);

        let mut iter = r.as_view().into_iter();
        assert_that!(iter.next(), eq(Some(0)));
        let mut clone = iter.clone();
        assert_that!(clone.next(), eq(Some(1)));
        assert_that!(iter.next(), eq(Some(1)));
    }
    #[gtest]
    fn test_first_last() {
        let mut r = Repeated::<i32>::new();
        assert!(r.as_view().first().is_none());
        assert!(r.as_view().last().is_none());
        assert!(r.as_mut().first().is_none());
        assert!(r.as_mut().last().is_none());

        let mut m = r.as_mut();
        m.push(10);
        assert_that!(m.first(), eq(Some(10)));
        assert_that!(m.last(), eq(Some(10)));
        assert_that!(m.as_view().first(), eq(Some(10)));
        assert_that!(m.as_view().last(), eq(Some(10)));

        m.push(20);
        assert_that!(m.first(), eq(Some(10)));
        assert_that!(m.last(), eq(Some(20)));
    }

    #[gtest]
    fn test_double_ended_iter() {
        let r: Repeated<i32> = [1, 2, 3].into_iter().collect();
        let mut iter = r.as_view().into_iter();
        assert_that!(iter.next(), eq(Some(1)));
        assert_that!(iter.next_back(), eq(Some(3)));
        assert_that!(iter.next(), eq(Some(2)));
        assert_that!(iter.next(), eq(None));
        assert_that!(iter.next_back(), eq(None));
    }

    #[gtest]
    fn test_from_iter() {
        let r: Repeated<i32> = [10, 20, 30].into_iter().collect();
        assert_that!(r.as_view(), elements_are![eq(10), eq(20), eq(30)]);
    }
}
