// Protocol Buffers - Google's data interchange format
// Copyright 2025 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 super::sys::{
    message::array as sys_array, message::map as sys_map, message::message as sys_msg,
    mini_table::mini_table as sys_mt,
};
use super::StringView;
use super::{Arena, AssociatedMiniTable};
use core::marker::PhantomData;
use paste::paste;

pub type RawMessage = sys_msg::RawMessage;

#[derive(Debug)]
pub struct MessagePtr<T> {
    raw: RawMessage,
    _phantom: PhantomData<T>,
}

impl<T> Copy for MessagePtr<T> {}

impl<T> Clone for MessagePtr<T> {
    fn clone(&self) -> Self {
        *self
    }
}

impl<T> MessagePtr<T> {
    pub fn raw(&self) -> RawMessage {
        self.raw
    }
}

macro_rules! scalar_accessors {
    ( $ty:ty, $rust_ty_name:ident, $upb_ty_name:ident) => {
        paste! {
            impl<T: AssociatedMiniTable> MessagePtr<T> {
                /// # Safety
                /// - `self` must be legally dereferenceable.
                /// - The field at `index` must be a $ty field.
                pub unsafe fn [< get_ $rust_ty_name _at_index >] (self, index: u32, default_value: $ty) -> $ty {
                    let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
                    unsafe { sys_msg::[< upb_Message_Get $upb_ty_name >](self.raw, f, default_value) }
                }

                /// # Safety
                /// - `self` must be legally dereferenceable to a mutable message.
                /// - The field at `index` must be a $ty field.
                pub unsafe fn [< set_base_field_ $rust_ty_name _at_index >] (self, index: u32, value: $ty) {
                    let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
                    unsafe { sys_msg::[< upb_Message_SetBaseField $upb_ty_name >](self.raw, f, value) }
                }
            }
        }
    };
}

scalar_accessors!(bool, bool, Bool);
scalar_accessors!(i32, i32, Int32);
scalar_accessors!(i64, i64, Int64);
scalar_accessors!(u32, u32, UInt32);
scalar_accessors!(u64, u64, UInt64);
scalar_accessors!(f32, f32, Float);
scalar_accessors!(f64, f64, Double);
scalar_accessors!(StringView, string, String);

impl<T: AssociatedMiniTable> MessagePtr<T> {
    /// Constructs a new mutable message pointer.
    /// Will only return None if arena allocation fails.
    pub fn new(arena: &Arena) -> Option<MessagePtr<T>> {
        let raw = unsafe { sys_msg::upb_Message_New(T::mini_table(), arena.raw()) };
        raw.map(|raw| MessagePtr { raw, _phantom: PhantomData })
    }

    /// # Safety
    /// - `raw` must be a dereferenceable message pointer of message associated with `T::mini_table()`.
    pub unsafe fn wrap(raw: RawMessage) -> MessagePtr<T> {
        MessagePtr { raw, _phantom: PhantomData }
    }

    /// # Safety
    /// - `self` must be legally dereferenceable to a mutable message.
    pub unsafe fn clear(self) {
        unsafe { sys_msg::upb_Message_Clear(self.raw, T::mini_table()) }
    }

    /// Copies the contents of `src` to `self`, using `arena` for allocations.
    /// `arena` should be the one associated with `self`.
    /// # Safety
    /// - `self` must be legally dereferenceable to a mutable message.
    pub unsafe fn deep_copy(self, src: Self, arena: &Arena) -> bool {
        unsafe { sys_msg::upb_Message_DeepCopy(self.raw, src.raw, T::mini_table(), arena.raw()) }
    }

    /// Returns a pointer to a mutable message which is a clone of `self` on `arena`.
    /// # Safety
    /// - `self` must be legally dereferenceable.
    pub unsafe fn deep_clone(self, arena: &Arena) -> Option<MessagePtr<T>> {
        let raw = unsafe { sys_msg::upb_Message_DeepClone(self.raw, T::mini_table(), arena.raw()) };
        raw.map(|raw| MessagePtr { raw, _phantom: PhantomData })
    }

    /// # Safety
    /// - `self` must be legally dereferenceable.
    /// - `index` must be within bounds of `T::mini_table()`.
    pub unsafe fn clear_field_at_index(self, index: u32) {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
        unsafe { sys_msg::upb_Message_ClearBaseField(self.raw, f) }
    }

    /// # Safety
    /// - `self` must be legally dereferenceable.
    /// - `index` must be within bounds of `T::mini_table()`.
    pub unsafe fn has_field_at_index(self, index: u32) -> bool {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
        unsafe { sys_msg::upb_Message_HasBaseField(self.raw, f) }
    }

    /// Returns a constant message pointer, or None if the field is not present.
    ///
    /// # Safety
    /// - `self` must be legally dereferenceable.
    /// - The field at `index` must be a message field of type `ChildT`.
    pub unsafe fn get_message_at_index<ChildT>(self, index: u32) -> Option<MessagePtr<ChildT>> {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };

        let raw = unsafe { sys_msg::upb_Message_GetMessage(self.raw, f) };
        raw.map(|raw| MessagePtr { raw, _phantom: PhantomData })
    }

    /// # Safety
    /// - `self` must be legally dereferenceable.
    /// - The field at `index` must be a message field of type `ChildT`.
    /// - Caller must ensure that `value` outlives `self` (typically by being on the same arena).
    pub unsafe fn set_base_field_message_at_index<ChildT>(
        self,
        index: u32,
        value: MessagePtr<ChildT>,
    ) {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
        unsafe { sys_msg::upb_Message_SetBaseFieldMessage(self.raw, f, value.raw) }
    }

    /// Returns a mutable message pointer, creating the field if it is not present.
    ///
    /// # Safety
    /// - `self` must be legally dereferenceable to a mutable message.
    /// - The field at `index` must be a message field of type `ChildT`.
    pub unsafe fn get_or_create_mutable_message_at_index<ChildT>(
        self,
        index: u32,
        arena: &Arena,
    ) -> Option<MessagePtr<ChildT>> {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };

        let raw = unsafe {
            sys_msg::upb_Message_GetOrCreateMutableMessage(
                self.raw,
                T::mini_table(),
                f,
                arena.raw(),
            )
        };
        raw.map(|raw| MessagePtr { raw, _phantom: PhantomData })
    }

    /// Returns a constant pointer to an array. May return None if the repeated field is empty.
    ///
    /// # Safety
    /// - `self` must be legally dereferenceable.
    /// - The field at `index` must be a repeated field.
    pub unsafe fn get_array_at_index(self, index: u32) -> Option<sys_array::RawArray> {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
        let raw = unsafe { sys_msg::upb_Message_GetArray(self.raw, f) };
        raw
    }

    /// # Safety
    /// - `self` must be legally dereferenceable.
    /// - The field at `index` must be a repeated field.
    /// - Caller must ensure that `value` outlives `self` (typically by being on the same arena).
    pub unsafe fn set_array_at_index(self, index: u32, value: sys_array::RawArray) {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
        let value_ptr: *const *const core::ffi::c_void =
            &(value.as_ptr() as *const core::ffi::c_void);
        unsafe {
            sys_msg::upb_Message_SetBaseField(self.raw, f, value_ptr as *const core::ffi::c_void)
        }
    }

    /// Returns a mutable pointer to an array. Will only return None if arena allocation fails.
    ///
    /// # Safety
    /// - `self` must be legally dereferenceable to a mutable message.
    /// - The field at `index` must be a repeated field.
    pub unsafe fn get_or_create_mutable_array_at_index(
        self,
        index: u32,
        arena: &Arena,
    ) -> Option<sys_array::RawArray> {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
        let raw = unsafe { sys_msg::upb_Message_GetOrCreateMutableArray(self.raw, f, arena.raw()) };
        raw
    }

    /// Returns a constant pointer to a map. May return None if the map is empty.
    ///
    /// # Safety
    /// - `self` must be legally dereferenceable.
    /// - The field at `index` must be a map.
    pub unsafe fn get_map_at_index(self, index: u32) -> Option<sys_map::RawMap> {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
        unsafe { sys_msg::upb_Message_GetMap(self.raw, f) }
    }

    /// # Safety
    /// - `self` must be legally dereferenceable.
    /// - The field at `index` must be a repeated field.
    /// - Caller must ensure that `value` outlives `self` (typically by being on the same arena).
    pub unsafe fn set_map_at_index(self, index: u32, value: sys_map::RawMap) {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
        let value_ptr: *const *const core::ffi::c_void =
            &(value.as_ptr() as *const core::ffi::c_void);
        unsafe {
            sys_msg::upb_Message_SetBaseField(self.raw, f, value_ptr as *const core::ffi::c_void)
        }
    }

    /// Returns a mutable pointer to a map. Will only return None if arena allocation fails.
    ///
    /// # Safety
    /// - `self` must be legally dereferenceable to a mutable message.
    /// - The field at `index` must be a map.
    pub unsafe fn get_or_create_mutable_map_at_index(
        self,
        index: u32,
        arena: &Arena,
    ) -> Option<sys_map::RawMap> {
        unsafe {
            let f = sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index);
            let map_entry_mini_table = sys_mt::upb_MiniTable_SubMessage(T::mini_table(), f);
            sys_msg::upb_Message_GetOrCreateMutableMap(
                self.raw,
                map_entry_mini_table,
                f,
                arena.raw(),
            )
        }
    }

    /// Returns the number associated with the active field in a oneof, or 0 if the oneof is unset.
    /// `index` can be the field number of any field in the oneof.
    ///
    /// # Safety
    /// - `self` must be legally dereferenceable.
    /// - The field at `index` must be part of a oneof.
    pub unsafe fn which_oneof_field_number_by_index(self, index: u32) -> u32 {
        let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
        unsafe { sys_msg::upb_Message_WhichOneofFieldNumber(self.raw, f) }
    }
}
