// Protocol Buffers - Google's data interchange format
// Copyright 2026 Google LLC
//
// 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 super::*;

unsafe extern "C" {
    fn proto2_rust_thunk_UntypedMapIterator_increment(iter: &mut UntypedMapIterator);

    pub fn proto2_rust_map_new(key_prototype: FfiMapValue, value_prototype: FfiMapValue) -> RawMap;
    pub fn proto2_rust_map_free(m: RawMap);
    pub fn proto2_rust_map_clear(m: RawMap);
    pub fn proto2_rust_map_size(m: RawMap) -> usize;
    pub fn proto2_rust_map_iter(m: RawMap, iter_mem: *mut c_void);
}

/// A trait implemented by types which are allowed as keys in maps.
/// This is all types for fields except for repeated, maps, bytes, messages, enums and floating
/// point types. This trait is defined separately in cpp.rs and upb.rs to be able to set better
/// subtrait bounds.
#[doc(hidden)]
pub trait MapKey: Proxied + FfiMapKey + CppMapTypeConversions + SealedInternal {}

#[derive(Debug)]
#[doc(hidden)]
pub struct InnerMap {
    pub(crate) raw: RawMap,
}

impl InnerMap {
    pub fn new(raw: RawMap) -> Self {
        Self { raw }
    }

    pub fn as_mut(&mut self) -> InnerMapMut<'_> {
        InnerMapMut { raw: self.raw, _phantom: PhantomData }
    }
}

#[derive(Clone, Copy, Debug)]
#[doc(hidden)]
pub struct InnerMapMut<'msg> {
    pub(crate) raw: RawMap,
    _phantom: PhantomData<&'msg ()>,
}

#[doc(hidden)]
impl<'msg> InnerMapMut<'msg> {
    pub fn new(raw: RawMap) -> Self {
        InnerMapMut { raw, _phantom: PhantomData }
    }

    pub fn as_raw(&self) -> RawMap {
        self.raw
    }
}

/// An untyped iterator in a map, produced via `.cbegin()` on a typed map.
///
/// This struct is ABI-compatible with `google::protobuf::internal::UntypedMapIterator`.
/// It is trivially constructible and destructible.
#[repr(C)]
#[doc(hidden)]
pub struct UntypedMapIterator {
    node: *mut c_void,
    map: *const c_void,
    bucket_index: u32,
}

impl UntypedMapIterator {
    /// Returns `true` if this iterator is at the end of the map.
    fn at_end(&self) -> bool {
        // This behavior is verified via test `IteratorNodeFieldIsNullPtrAtEnd`.
        self.node.is_null()
    }

    /// Assumes that the map iterator is for the input types, gets the current
    /// entry, and moves the iterator forward to the next entry.
    ///
    /// Conversion to and from FFI types is provided by the user.
    /// This is a helper function for implementing
    /// `MapValue::iter_next`.
    ///
    /// # Safety
    /// - The backing map must be valid and not be mutated for `'a`.
    /// - The thunk must be safe to call if the iterator is not at the end of the map.
    /// - The thunk must always write to the `key` and `value` fields, but not read from them.
    /// - The get thunk must not move the iterator forward or backward.
    #[inline(always)]
    pub unsafe fn next_unchecked<'a, K, V, FfiKey, FfiValue>(
        &mut self,

        iter_get_thunk: unsafe fn(
            iter: &mut UntypedMapIterator,
            key: *mut FfiKey,
            value: *mut FfiValue,
        ),
        from_ffi_key: impl FnOnce(FfiKey) -> View<'a, K>,
        from_ffi_value: impl FnOnce(FfiValue) -> View<'a, V>,
    ) -> Option<(View<'a, K>, View<'a, V>)>
    where
        K: MapKey + 'a,
        V: MapValue + 'a,
    {
        if self.at_end() {
            return None;
        }
        let mut ffi_key = MaybeUninit::uninit();
        let mut ffi_value = MaybeUninit::uninit();
        // SAFETY:
        // - The backing map outlives `'a`.
        // - The iterator is not at the end (node is non-null).
        // - `ffi_key` and `ffi_value` are not read (as uninit) as promised by the caller.
        unsafe { (iter_get_thunk)(self, ffi_key.as_mut_ptr(), ffi_value.as_mut_ptr()) }

        // SAFETY:
        // - The backing map is alive as promised by the caller.
        // - `self.at_end()` is false and the `get` does not change that.
        // - `UntypedMapIterator` has the same ABI as `google::protobuf::internal::UntypedMapIterator`. It is
        //   statically checked to be:
        //   - Trivially copyable.
        //   - Trivially destructible.
        //   - Standard layout.
        //   - The size and alignment of the Rust type above.
        //   - With the `node_` field first.
        unsafe { proto2_rust_thunk_UntypedMapIterator_increment(self) }

        // SAFETY:
        // - The `get` function always writes valid values to `ffi_key` and `ffi_value` as promised
        //   by the caller.
        unsafe {
            Some((from_ffi_key(ffi_key.assume_init()), from_ffi_value(ffi_value.assume_init())))
        }
    }
}

// LINT.IfChange(map_ffi)
#[doc(hidden)]
#[repr(u8)]
#[derive(Debug, PartialEq)]
// Copy of UntypedMapBase::TypeKind
pub enum FfiMapValueTag {
    Bool,
    U32,
    U64,
    F32,
    F64,
    String,
    Message,
}
// For the purposes of FFI, we treat all integral types of a given size the same
// way. For example, u32 and i32 values are all represented as a u32.
// Likewise, u64 and i64 values are all stored in a u64.
#[doc(hidden)]
#[repr(C)]
pub union FfiMapValueUnion {
    pub b: bool,
    pub u: u32,
    pub uu: u64,
    pub f: f32,
    pub ff: f64,
    // Generally speaking, if s is set then it should not be None. However, we
    // do set it to None in the special case where the FfiMapValue is just a
    // "prototype" (see below). In that scenario, we just want to indicate the
    // value type without having to allocate a real C++ std::string.
    pub s: Option<CppStdString>,
    pub m: RawMessage,
}

// We use this tagged union to represent map values for the purposes of FFI.
#[doc(hidden)]
#[repr(C)]
pub struct FfiMapValue {
    pub tag: FfiMapValueTag,
    pub val: FfiMapValueUnion,
}
// LINT.ThenChange(//depot/google3/third_party/protobuf/rust/cpp_kernel/map.cc:
// map_ffi)

impl FfiMapValue {
    fn make_bool(b: bool) -> Self {
        FfiMapValue { tag: FfiMapValueTag::Bool, val: FfiMapValueUnion { b } }
    }

    pub fn make_u32(u: u32) -> Self {
        FfiMapValue { tag: FfiMapValueTag::U32, val: FfiMapValueUnion { u } }
    }

    fn make_u64(uu: u64) -> Self {
        FfiMapValue { tag: FfiMapValueTag::U64, val: FfiMapValueUnion { uu } }
    }

    pub fn make_f32(f: f32) -> Self {
        FfiMapValue { tag: FfiMapValueTag::F32, val: FfiMapValueUnion { f } }
    }

    fn make_f64(ff: f64) -> Self {
        FfiMapValue { tag: FfiMapValueTag::F64, val: FfiMapValueUnion { ff } }
    }

    fn make_string(s: CppStdString) -> Self {
        FfiMapValue { tag: FfiMapValueTag::String, val: FfiMapValueUnion { s: Some(s) } }
    }

    pub fn make_message(m: RawMessage) -> Self {
        FfiMapValue { tag: FfiMapValueTag::Message, val: FfiMapValueUnion { m } }
    }
}

pub trait CppMapTypeConversions: Proxied {
    // We have a notion of a map value "prototype", which is a FfiMapValue that
    // contains just enough information to indicate the value type of the map.
    // We need this on the C++ side to be able to determine size and offset
    // information about the map entry. For messages, the prototype is
    // the message default instance. For all other types, it is just a FfiMapValue
    // with the appropriate tag.
    fn get_prototype() -> FfiMapValue;

    fn to_map_value(self) -> FfiMapValue;

    /// # Safety
    /// - `value` must store the correct type for `Self`. If it is a string or bytes, then it must
    ///   not be None. If `Self` is a closed enum, then `value` must store a valid value for that
    ///   enum. If `Self` is a message, then `value` must store a message of the same type.
    /// - The value must be valid for `'a` lifetime.
    unsafe fn from_map_value<'a>(value: FfiMapValue) -> View<'a, Self>;

    /// # Safety
    /// - `value` must store a message of the same type as `Self`.
    /// - `value` must be valid and have exclusive mutable access for `'a` lifetime.
    #[allow(unused_variables)]
    unsafe fn mut_from_map_value<'a>(value: FfiMapValue) -> Mut<'a, Self>
    where
        Self: Message,
    {
        panic!("mut_from_map_value is only implemented for messages")
    }
}

impl CppMapTypeConversions for u32 {
    fn get_prototype() -> FfiMapValue {
        FfiMapValue::make_u32(0)
    }
    fn to_map_value(self) -> FfiMapValue {
        FfiMapValue::make_u32(self)
    }
    unsafe fn from_map_value<'a>(value: FfiMapValue) -> View<'a, Self> {
        debug_assert_eq!(value.tag, FfiMapValueTag::U32);
        unsafe { value.val.u }
    }
}

impl CppMapTypeConversions for i32 {
    fn get_prototype() -> FfiMapValue {
        FfiMapValue::make_u32(0)
    }
    fn to_map_value(self) -> FfiMapValue {
        FfiMapValue::make_u32(self as u32)
    }
    unsafe fn from_map_value<'a>(value: FfiMapValue) -> View<'a, Self> {
        debug_assert_eq!(value.tag, FfiMapValueTag::U32);
        unsafe { value.val.u as i32 }
    }
}

impl CppMapTypeConversions for u64 {
    fn get_prototype() -> FfiMapValue {
        FfiMapValue::make_u64(0)
    }
    fn to_map_value(self) -> FfiMapValue {
        FfiMapValue::make_u64(self)
    }
    unsafe fn from_map_value<'a>(value: FfiMapValue) -> View<'a, Self> {
        debug_assert_eq!(value.tag, FfiMapValueTag::U64);
        unsafe { value.val.uu }
    }
}

impl CppMapTypeConversions for i64 {
    fn get_prototype() -> FfiMapValue {
        FfiMapValue::make_u64(0)
    }
    fn to_map_value(self) -> FfiMapValue {
        FfiMapValue::make_u64(self as u64)
    }
    unsafe fn from_map_value<'a>(value: FfiMapValue) -> View<'a, Self> {
        debug_assert_eq!(value.tag, FfiMapValueTag::U64);
        unsafe { value.val.uu as i64 }
    }
}

impl CppMapTypeConversions for f32 {
    fn get_prototype() -> FfiMapValue {
        FfiMapValue::make_f32(0f32)
    }
    fn to_map_value(self) -> FfiMapValue {
        FfiMapValue::make_f32(self)
    }
    unsafe fn from_map_value<'a>(value: FfiMapValue) -> View<'a, Self> {
        debug_assert_eq!(value.tag, FfiMapValueTag::F32);
        unsafe { value.val.f }
    }
}

impl CppMapTypeConversions for f64 {
    fn get_prototype() -> FfiMapValue {
        FfiMapValue::make_f64(0.0)
    }
    fn to_map_value(self) -> FfiMapValue {
        FfiMapValue::make_f64(self)
    }
    unsafe fn from_map_value<'a>(value: FfiMapValue) -> View<'a, Self> {
        debug_assert_eq!(value.tag, FfiMapValueTag::F64);
        unsafe { value.val.ff }
    }
}

impl CppMapTypeConversions for bool {
    fn get_prototype() -> FfiMapValue {
        FfiMapValue::make_bool(false)
    }
    fn to_map_value(self) -> FfiMapValue {
        FfiMapValue::make_bool(self)
    }
    unsafe fn from_map_value<'a>(value: FfiMapValue) -> View<'a, Self> {
        debug_assert_eq!(value.tag, FfiMapValueTag::Bool);
        unsafe { value.val.b }
    }
}

impl CppMapTypeConversions for ProtoString {
    fn get_prototype() -> FfiMapValue {
        FfiMapValue { tag: FfiMapValueTag::String, val: FfiMapValueUnion { s: None } }
    }

    fn to_map_value(self) -> FfiMapValue {
        FfiMapValue::make_string(protostr_into_cppstdstring(self))
    }

    unsafe fn from_map_value<'a>(value: FfiMapValue) -> &'a ProtoStr {
        debug_assert_eq!(value.tag, FfiMapValueTag::String);
        unsafe { ptrlen_to_str(proto2_rust_cpp_string_to_view(value.val.s.unwrap())) }
    }
}

impl CppMapTypeConversions for ProtoBytes {
    fn get_prototype() -> FfiMapValue {
        FfiMapValue { tag: FfiMapValueTag::String, val: FfiMapValueUnion { s: None } }
    }

    fn to_map_value(self) -> FfiMapValue {
        FfiMapValue::make_string(protobytes_into_cppstdstring(self))
    }

    unsafe fn from_map_value<'a>(value: FfiMapValue) -> &'a [u8] {
        debug_assert_eq!(value.tag, FfiMapValueTag::String);
        unsafe { proto2_rust_cpp_string_to_view(value.val.s.unwrap()).as_ref() }
    }
}

// This trait encapsulates functionality that is specific to each map key type.
// We need this primarily so that we can call the appropriate FFI function for
// the key type.
#[doc(hidden)]
pub trait FfiMapKey
where
    Self: Proxied,
{
    type FfiKey;

    /// Converts a key written by `iter_get` into a view.
    ///
    /// # Safety
    /// - If `Self::FfiKey` borrows memory (e.g. `PtrAndLen`), that memory must be valid and
    ///   immutable for the lifetime `'a`.
    unsafe fn to_view<'a>(key: Self::FfiKey) -> View<'a, Self>;

    unsafe fn insert(m: RawMap, key: View<'_, Self>, value: FfiMapValue) -> bool;

    unsafe fn get(m: RawMap, key: View<'_, Self>, value: *mut FfiMapValue) -> bool;

    unsafe fn iter_get(
        iter: &mut UntypedMapIterator,
        key: *mut Self::FfiKey,
        value: *mut FfiMapValue,
    );

    unsafe fn remove(m: RawMap, key: View<'_, Self>) -> bool;
}

macro_rules! generate_map_key_impl {
    ( $($key:ty, $mutable_ffi_key:ty, $to_ffi:expr, $from_ffi:expr;)* ) => {
        paste! {
        $(
        impl FfiMapKey for $key {
            type FfiKey = $mutable_ffi_key;

            #[inline]
            // `$from_ffi` is the safe `identity` for scalar keys.
            #[allow(unused_unsafe)]
            unsafe fn to_view<'a>(key: Self::FfiKey) -> View<'a, Self> {
                // SAFETY: the caller guarantees that any memory borrowed by
                // `key` is valid and immutable for `'a`.
                unsafe { $from_ffi(key) }
            }

            #[inline]
            unsafe fn insert(
                m: RawMap,
                key: View<'_, Self>,
                value: FfiMapValue,
            ) -> bool {
                unsafe { [< proto2_rust_map_insert_ $key >](m, $to_ffi(key), value) }
            }

            #[inline]
            unsafe fn get(
                m: RawMap,
                key: View<'_, Self>,
                value: *mut FfiMapValue,
            ) -> bool {
                unsafe { [< proto2_rust_map_get_ $key >](m, $to_ffi(key), value) }
            }

            #[inline]
            unsafe fn iter_get(
                iter: &mut UntypedMapIterator,
                key: *mut Self::FfiKey,
                value: *mut FfiMapValue,
            ) {
                unsafe { [< proto2_rust_map_iter_get_ $key >](iter, key, value) }
            }

            #[inline]
            unsafe fn remove(m: RawMap, key: View<'_, Self>) -> bool {
                unsafe { [< proto2_rust_map_remove_ $key >](m, $to_ffi(key)) }
            }
        }
        )*
        }
    }
}

generate_map_key_impl!(
    bool, bool, identity, identity;
    i32, i32, identity, identity;
    u32, u32, identity, identity;
    i64, i64, identity, identity;
    u64, u64, identity, identity;
    ProtoString, PtrAndLen, str_to_ptrlen, ptrlen_to_str;
);

impl<Value> MapValue for Value
where
    Value: Singular + CppMapTypeConversions,
{
    fn map_new<Key: MapKey>(_private: Private) -> Map<Key, Self> {
        unsafe {
            Map::from_inner(
                Private,
                InnerMap::new(proto2_rust_map_new(Key::get_prototype(), Value::get_prototype())),
            )
        }
    }

    unsafe fn map_free<Key: MapKey>(_private: Private, map: &mut Map<Key, Self>) {
        unsafe {
            proto2_rust_map_free(map.as_raw(Private));
        }
    }

    fn map_clear<Key: MapKey>(_private: Private, mut map: MapMut<Key, Self>) {
        unsafe {
            proto2_rust_map_clear(map.as_raw(Private));
        }
    }

    fn map_len<Key: MapKey>(_private: Private, map: MapView<Key, Self>) -> usize {
        unsafe { proto2_rust_map_size(map.as_raw(Private)) }
    }

    fn map_insert<Key: MapKey>(
        _private: Private,
        mut map: MapMut<Key, Self>,
        key: View<'_, Key>,
        value: impl IntoProxied<Self>,
    ) -> bool {
        unsafe { Key::insert(map.as_raw(Private), key, value.into_proxied(Private).to_map_value()) }
    }

    fn map_get<'a, Key: MapKey>(
        _private: Private,
        map: MapView<'a, Key, Self>,
        key: View<'_, Key>,
    ) -> Option<View<'a, Self>> {
        let mut value = std::mem::MaybeUninit::uninit();
        let found = unsafe { Key::get(map.as_raw(Private), key, value.as_mut_ptr()) };
        if !found {
            return None;
        }
        unsafe { Some(Self::from_map_value(value.assume_init())) }
    }

    fn map_get_mut<'a, Key: MapKey>(
        _private: Private,
        mut map: MapMut<'a, Key, Self>,
        key: View<'_, Key>,
    ) -> Option<Mut<'a, Self>>
    where
        Value: Message,
    {
        let mut value = std::mem::MaybeUninit::uninit();
        let found = unsafe { Key::get(map.as_raw(Private), key, value.as_mut_ptr()) };
        if !found {
            return None;
        }
        // SAFETY: `value` has been initialized because it was found.
        // - `value` is a message as required by the trait.
        // - `value` is valid for the `'a` lifetime of the `MapMut`.
        unsafe { Some(Self::mut_from_map_value(value.assume_init())) }
    }

    fn map_remove<Key: MapKey>(
        _private: Private,
        mut map: MapMut<Key, Self>,
        key: View<'_, Key>,
    ) -> bool {
        unsafe { Key::remove(map.as_raw(Private), key) }
    }

    fn map_iter<Key: MapKey>(_private: Private, map: MapView<Key, Self>) -> MapIter<Key, Self> {
        // Out-param instead of a by-value return; see `proto2_rust_map_iter` in
        // cpp_kernel/map.cc for why.
        let mut iter = MaybeUninit::<UntypedMapIterator>::uninit();
        // SAFETY:
        // - The backing map for `map.as_raw` is valid for at least '_.
        // - A View that is live for '_ guarantees the backing map is unmodified for '_.
        // - The `iter` function initializes an iterator that is valid for the key and value types,
        //   and live for at least '_.
        unsafe {
            proto2_rust_map_iter(map.as_raw(Private), iter.as_mut_ptr().cast());
            MapIter::from_raw(Private, iter.assume_init())
        }
    }

    fn map_iter_next<'a, Key: MapKey>(
        _private: Private,
        iter: &mut MapIter<'a, Key, Self>,
    ) -> Option<(View<'a, Key>, View<'a, Self>)> {
        // SAFETY:
        // - The `MapIter` API forbids the backing map from being mutated for 'a, and guarantees
        //   that it's the correct key and value types.
        // - The thunk is safe to call as long as the iterator isn't at the end.
        // - The thunk always writes to key and value fields and does not read.
        // - The thunk does not increment the iterator.
        // - The key and value written by the thunk borrow from the backing map, so `to_view` and
        //   `from_map_value` can treat them as valid for 'a.
        unsafe {
            iter.as_raw_mut(Private).next_unchecked::<Key, Self, _, _>(
                |iter, key, value| Key::iter_get(iter, key, value),
                |ffi_key| Key::to_view(ffi_key),
                |value| Self::from_map_value(value),
            )
        }
    }
}

macro_rules! impl_map_primitives {
    (@impl $(($rust_type:ty, $cpp_type:ty) => [
        $insert_thunk:ident,
        $get_thunk:ident,
        $iter_get_thunk:ident,
        $remove_thunk:ident,
    ]),* $(,)?) => {
        $(
            unsafe extern "C" {
                pub fn $insert_thunk(
                    m: RawMap,
                    key: $cpp_type,
                    value: FfiMapValue,
                ) -> bool;
                pub fn $get_thunk(
                    m: RawMap,
                    key: $cpp_type,
                    value: *mut FfiMapValue,
                ) -> bool;
                pub fn $iter_get_thunk(
                    iter: &mut UntypedMapIterator,
                    key: *mut $cpp_type,
                    value: *mut FfiMapValue,
                );
                pub fn $remove_thunk(m: RawMap, key: $cpp_type) -> bool;
            }
        )*
    };
    ($($rust_type:ty, $cpp_type:ty;)* $(,)?) => {
        paste!{
            impl_map_primitives!(@impl $(
                    ($rust_type, $cpp_type) => [
                    [< proto2_rust_map_insert_ $rust_type >],
                    [< proto2_rust_map_get_ $rust_type >],
                    [< proto2_rust_map_iter_get_ $rust_type >],
                    [< proto2_rust_map_remove_ $rust_type >],
                ],
            )*);
        }
    };
}

impl_map_primitives!(
    i32, i32;
    u32, u32;
    i64, i64;
    u64, u64;
    bool, bool;
    ProtoString, PtrAndLen;
);
