// 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

/// 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::{
    Mut, MutProxy, Proxied, SettableValue, View, ViewProxy,
    __internal::{Private, RawRepeatedField},
    __runtime::{RepeatedField, RepeatedFieldInner},
    primitive::PrimitiveMut,
    vtable::ProxiedWithRawVTable,
};

#[derive(Clone, Copy)]
pub struct RepeatedFieldRef<'a> {
    pub repeated_field: RawRepeatedField,
    pub _phantom: PhantomData<&'a mut ()>,
}

unsafe impl<'a> Send for RepeatedFieldRef<'a> {}
unsafe impl<'a> Sync for RepeatedFieldRef<'a> {}

#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct RepeatedView<'a, T: ?Sized> {
    inner: RepeatedField<'a, T>,
}

unsafe impl<'a, T: ProxiedWithRawVTable> Sync for RepeatedView<'a, T> {}
unsafe impl<'a, T: ProxiedWithRawVTable> Send for RepeatedView<'a, T> {}

impl<'msg, T: ?Sized> RepeatedView<'msg, T> {
    pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self {
        Self { inner: RepeatedField::<'msg>::from_inner(_private, inner) }
    }
}

pub struct RepeatedFieldIter<'a, T> {
    inner: RepeatedField<'a, T>,
    current_index: usize,
}

impl<'a, T> std::fmt::Debug for RepeatedView<'a, T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_tuple("RepeatedView").finish()
    }
}

#[repr(transparent)]
#[derive(Debug)]
pub struct RepeatedMut<'a, T: ?Sized> {
    inner: RepeatedField<'a, T>,
}

unsafe impl<'a, T: ProxiedWithRawVTable> Sync for RepeatedMut<'a, T> {}

impl<'msg, T: ?Sized> RepeatedMut<'msg, T> {
    pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self {
        Self { inner: RepeatedField::from_inner(_private, inner) }
    }
    pub fn as_mut(&self) -> RepeatedMut<'_, T> {
        Self { inner: self.inner }
    }
}

impl<'a, T> std::ops::Deref for RepeatedMut<'a, T> {
    type Target = RepeatedView<'a, T>;
    fn deref(&self) -> &Self::Target {
        // SAFETY:
        //   - `Repeated{View,Mut}<'a, T>` are both `#[repr(transparent)]` over
        //     `RepeatedField<'a, T>`.
        //   - `RepeatedField` is a type alias for `NonNull`.
        unsafe { &*(self as *const Self as *const RepeatedView<'a, T>) }
    }
}

pub struct RepeatedFieldIterMut<'a, T> {
    inner: RepeatedMut<'a, T>,
    current_index: usize,
}

pub struct Repeated<T>(PhantomData<T>);

macro_rules! impl_repeated_primitives {
    ($($t:ty),*) => {
        $(
            impl Proxied for Repeated<$t> {
                type View<'a> = RepeatedView<'a, $t>;
                type Mut<'a> = RepeatedMut<'a, $t>;
            }

            impl<'a> ViewProxy<'a> for RepeatedView<'a, $t> {
                type Proxied = Repeated<$t>;

                fn as_view(&self) -> View<'_, Self::Proxied> {
                    *self
                }

                fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
                where 'a: 'shorter,
                {
                    RepeatedView { inner: self.inner }
                }
            }

            impl<'a> ViewProxy<'a> for RepeatedMut<'a, $t> {
                type Proxied = Repeated<$t>;

                fn as_view(&self) -> View<'_, Self::Proxied> {
                    **self
                }

                fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
                where 'a: 'shorter,
                {
                    *self.into_mut::<'shorter>()
                }
            }

            impl<'a> MutProxy<'a> for RepeatedMut<'a, $t> {
                fn as_mut(&mut self) -> Mut<'_, Self::Proxied> {
                    RepeatedMut { inner: self.inner }
                }

                fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied>
                where 'a: 'shorter,
                {
                    RepeatedMut { inner: self.inner }
                }
            }

            impl <'a> SettableValue<Repeated<$t>> for RepeatedView<'a, $t> {
                fn set_on(self, _private: Private, mut mutator: Mut<'_, Repeated<$t>>) {
                    mutator.copy_from(self);
                }
            }

            impl<'a> RepeatedView<'a, $t> {
                pub fn len(&self) -> usize {
                    self.inner.len()
                }
                pub fn is_empty(&self) -> bool {
                    self.len() == 0
                }
                pub fn get(&self, index: usize) -> Option<$t> {
                    self.inner.get(index)
                }
                pub fn iter(&self) -> RepeatedFieldIter<'_, $t> {
                    (*self).into_iter()
                }
            }

            impl<'a> RepeatedMut<'a, $t> {
                pub fn push(&mut self, val: $t) {
                    self.inner.push(val)
                }
                pub fn set(&mut self, index: usize, val: $t) {
                    self.inner.set(index, val)
                }
                pub fn get_mut(&mut self, index: usize) -> Option<Mut<'_, $t>> {
                    if index >= self.len() {
                        return None;
                    }
                    Some(PrimitiveMut::Repeated(self.as_mut(), index))
                }
                pub fn iter(&self) -> RepeatedFieldIter<'_, $t> {
                    self.as_view().into_iter()
                }
                pub fn iter_mut(&mut self) -> RepeatedFieldIterMut<'_, $t> {
                    self.as_mut().into_iter()
                }
                pub fn copy_from(&mut self, src: RepeatedView<'_, $t>) {
                    self.inner.copy_from(&src.inner);
                }
            }

            impl<'a> std::iter::Iterator for RepeatedFieldIter<'a, $t> {
                type Item = $t;
                fn next(&mut self) -> Option<Self::Item> {
                    let val = self.inner.get(self.current_index);
                    if val.is_some() {
                        self.current_index += 1;
                    }
                    val
                }
            }

            impl<'a> std::iter::IntoIterator for RepeatedView<'a, $t> {
                type Item = $t;
                type IntoIter = RepeatedFieldIter<'a, $t>;
                fn into_iter(self) -> Self::IntoIter {
                    RepeatedFieldIter { inner: self.inner, current_index: 0 }
                }
            }

            impl <'a> std::iter::Iterator for RepeatedFieldIterMut<'a, $t> {
                type Item = Mut<'a, $t>;
                fn next(&mut self) -> Option<Self::Item> {
                    if self.current_index >= self.inner.len() {
                        return None;
                    }
                    let elem = PrimitiveMut::Repeated(
                        // While this appears to allow mutable aliasing
                        // (multiple `Self::Item`s can co-exist), each `Item`
                        // only references a specific unique index.
                        RepeatedMut{ inner: self.inner.inner },
                        self.current_index,
                    );
                    self.current_index += 1;
                    Some(elem)
                }
            }

            impl<'a> std::iter::IntoIterator for RepeatedMut<'a, $t> {
                type Item = Mut<'a, $t>;
                type IntoIter = RepeatedFieldIterMut<'a, $t>;
                fn into_iter(self) -> Self::IntoIter {
                    RepeatedFieldIterMut { inner: self, current_index: 0 }
                }
            }
        )*
    }
}

impl_repeated_primitives!(i32, u32, bool, f32, f64, i64, u64);
