// 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 crate::__internal::{Private, PtrAndLen, RawMessage};
use crate::__runtime::{copy_bytes_in_arena_if_needed_by_runtime, MutatorMessageRef};
use crate::{
    AbsentField, FieldEntry, Mut, MutProxy, Optional, PresentField, Proxied, ProxiedWithPresence,
    View, ViewProxy,
};
use std::fmt::{self, Debug};

/// A proxied type that can use a vtable to provide get/set access for a
/// present field.
///
/// This vtable should consist of `unsafe fn`s that call thunks that operate on
/// `RawMessage`. The structure of this vtable is different per proxied type.
pub trait ProxiedWithRawVTable: Proxied {
    /// The vtable for get/set access, stored in static memory.
    type VTable: Debug + 'static;

    fn make_view(_private: Private, mut_inner: RawVTableMutator<'_, Self>) -> View<'_, Self>;
    fn make_mut(_private: Private, inner: RawVTableMutator<'_, Self>) -> Mut<'_, Self>;
}

/// A proxied type that can use a vtable to provide get/set/clear access for
/// an optional field.
///
/// This vtable should consist of `unsafe fn`s that call thunks that operate on
/// `RawMessage`. The structure of this vtable is different per-proxied type.
pub trait ProxiedWithRawOptionalVTable: ProxiedWithRawVTable + ProxiedWithPresence {
    /// The vtable for get/set/clear, must contain `Self::VTable`.
    type OptionalVTable: Debug + 'static;

    /// Cast from a static reference of `OptionalVTable` to `VTable`.
    /// This should mean `OptionalVTable` contains a `VTable`.
    fn upcast_vtable(
        _private: Private,
        optional_vtable: &'static Self::OptionalVTable,
    ) -> &'static Self::VTable;
}

/// Constructs a new field entry from a raw message, a vtable for manipulation,
/// and an eager check for whether the value is present or not.
///
/// # Safety
/// - `msg_ref` must be valid to provide as an argument for `vtable`'s methods
///   for `'msg`.
/// - If given `msg_ref` as an argument, any values returned by `vtable` methods
///   must be valid for `'msg`.
/// - Operations on the vtable must be thread-compatible.
#[doc(hidden)]
pub unsafe fn new_vtable_field_entry<'msg, T: ProxiedWithRawOptionalVTable + ?Sized>(
    _private: Private,
    msg_ref: MutatorMessageRef<'msg>,
    optional_vtable: &'static T::OptionalVTable,
    is_set: bool,
) -> FieldEntry<'msg, T>
where
    T: ProxiedWithPresence<
            PresentMutData<'msg> = RawVTableOptionalMutatorData<'msg, T>,
            AbsentMutData<'msg> = RawVTableOptionalMutatorData<'msg, T>,
        >,
{
    let data = RawVTableOptionalMutatorData { msg_ref, vtable: optional_vtable };
    if is_set {
        Optional::Set(PresentField::from_inner(Private, data))
    } else {
        Optional::Unset(AbsentField::from_inner(Private, data))
    }
}

/// The internal implementation type for a vtable-based `protobuf::Mut<T>`.
///
/// This stores the two components necessary to mutate the field:
/// borrowed message data and a vtable reference.
///
/// The borrowed message data varies per runtime: C++ needs a message pointer,
/// while UPB needs a message pointer and an `&Arena`.
///
/// Implementations of `ProxiedWithRawVTable` implement get/set
/// on top of `RawVTableMutator<T>`, and the top-level mutator (e.g.
/// `BytesMut`) calls these methods.
///
/// [`RawVTableOptionalMutatorData`] is similar, but also includes the
/// capability to has/clear.
pub struct RawVTableMutator<'msg, T: ProxiedWithRawVTable + ?Sized> {
    msg_ref: MutatorMessageRef<'msg>,
    vtable: &'static T::VTable,
}

// These use manual impls instead of derives to avoid unnecessary bounds on `T`.
// This problem is referred to as "perfect derive".
// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/
impl<'msg, T: ProxiedWithRawVTable + ?Sized> Clone for RawVTableMutator<'msg, T> {
    fn clone(&self) -> Self {
        *self
    }
}
impl<'msg, T: ProxiedWithRawVTable + ?Sized> Copy for RawVTableMutator<'msg, T> {}

impl<'msg, T: ProxiedWithRawVTable + ?Sized> Debug for RawVTableMutator<'msg, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RawVTableMutator")
            .field("msg_ref", &self.msg_ref)
            .field("vtable", &self.vtable)
            .finish()
    }
}

impl<'msg, T: ProxiedWithRawVTable + ?Sized> RawVTableMutator<'msg, T> {
    /// # Safety
    /// - `msg_ref` must be valid to provide as an argument for `vtable`'s
    ///   methods for `'msg`.
    /// - If given `msg_ref` as an argument, any values returned by `vtable`
    ///   methods must be valid for `'msg`.
    #[doc(hidden)]
    pub unsafe fn new(
        _private: Private,
        msg_ref: MutatorMessageRef<'msg>,
        vtable: &'static T::VTable,
    ) -> Self {
        RawVTableMutator { msg_ref, vtable }
    }
}

/// [`RawVTableMutator`], but also includes has/clear.
///
/// This is used as the `PresentData` and `AbsentData` for `impl
/// ProxiedWithPresence for T`. In that implementation, `clear_present_field`
/// and `set_absent_to_default` will use methods implemented on
/// `RawVTableOptionalMutatorData<T>` to do the setting and clearing.
///
/// This has the same representation for "present" and "absent" data;
/// differences like default values are obviated by the vtable.
pub struct RawVTableOptionalMutatorData<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> {
    msg_ref: MutatorMessageRef<'msg>,
    vtable: &'static T::OptionalVTable,
}

unsafe impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> Sync
    for RawVTableOptionalMutatorData<'msg, T>
{
}

// These use manual impls instead of derives to avoid unnecessary bounds on `T`.
// This problem is referred to as "perfect derive".
// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/
impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> Clone
    for RawVTableOptionalMutatorData<'msg, T>
{
    fn clone(&self) -> Self {
        *self
    }
}
impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> Copy
    for RawVTableOptionalMutatorData<'msg, T>
{
}

impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> Debug
    for RawVTableOptionalMutatorData<'msg, T>
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RawVTableOptionalMutatorData")
            .field("msg_ref", &self.msg_ref)
            .field("vtable", &self.vtable)
            .finish()
    }
}

impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> RawVTableOptionalMutatorData<'msg, T> {
    /// # Safety
    /// - `msg_ref` must be valid to provide as an argument for `vtable`'s
    ///   methods for `'msg`.
    /// - If given `msg_ref` as an argument, any values returned by `vtable`
    ///   methods must be valid for `'msg`.
    #[doc(hidden)]
    pub unsafe fn new(
        _private: Private,
        msg_ref: MutatorMessageRef<'msg>,
        vtable: &'static T::OptionalVTable,
    ) -> Self {
        Self { msg_ref, vtable }
    }

    fn into_raw_mut(self) -> RawVTableMutator<'msg, T> {
        RawVTableMutator { msg_ref: self.msg_ref, vtable: T::upcast_vtable(Private, self.vtable) }
    }
}

impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized + 'msg> ViewProxy<'msg>
    for RawVTableOptionalMutatorData<'msg, T>
{
    type Proxied = T;

    fn as_view(&self) -> View<'_, T> {
        T::make_view(Private, self.into_raw_mut())
    }

    fn into_view<'shorter>(self) -> View<'shorter, T>
    where
        'msg: 'shorter,
    {
        T::make_view(Private, self.into_raw_mut())
    }
}

// Note: though this raw value implements `MutProxy`, the `as_mut` is only valid
// when the field is known to be present. `FieldEntry` enforces this in its
// design: `AbsentField { inner: RawVTableOptionalMutatorData<T> }` does not
// implement `MutProxy`.
impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized + 'msg> MutProxy<'msg>
    for RawVTableOptionalMutatorData<'msg, T>
{
    fn as_mut(&mut self) -> Mut<'_, T> {
        T::make_mut(Private, self.into_raw_mut())
    }

    fn into_mut<'shorter>(self) -> Mut<'shorter, T>
    where
        'msg: 'shorter,
    {
        T::make_mut(Private, self.into_raw_mut())
    }
}

impl ProxiedWithRawVTable for [u8] {
    type VTable = BytesMutVTable;

    fn make_view(_private: Private, mut_inner: RawVTableMutator<'_, Self>) -> View<'_, Self> {
        mut_inner.get()
    }

    fn make_mut(_private: Private, inner: RawVTableMutator<'_, Self>) -> Mut<'_, Self> {
        crate::string::BytesMut::from_inner(Private, inner)
    }
}

impl ProxiedWithRawOptionalVTable for [u8] {
    type OptionalVTable = BytesOptionalMutVTable;
    fn upcast_vtable(
        _private: Private,
        optional_vtable: &'static Self::OptionalVTable,
    ) -> &'static Self::VTable {
        &optional_vtable.base
    }
}

/// A generic thunk vtable for mutating a present primitive field.
#[doc(hidden)]
#[derive(Debug)]
pub struct PrimitiveVTable<T> {
    pub(crate) setter: unsafe extern "C" fn(msg: RawMessage, val: T),
    pub(crate) getter: unsafe extern "C" fn(msg: RawMessage) -> T,
}

#[doc(hidden)]
#[derive(Debug)]
/// A generic thunk vtable for mutating an `optional` primitive field.
pub struct PrimitiveOptionalMutVTable<T> {
    pub(crate) base: PrimitiveVTable<T>,
    pub(crate) clearer: unsafe extern "C" fn(msg: RawMessage),
    pub(crate) default: T,
}

impl<T> PrimitiveVTable<T> {
    #[doc(hidden)]
    pub const fn new(
        _private: Private,
        getter: unsafe extern "C" fn(msg: RawMessage) -> T,
        setter: unsafe extern "C" fn(msg: RawMessage, val: T),
    ) -> Self {
        Self { getter, setter }
    }
}

impl<T> PrimitiveOptionalMutVTable<T> {
    #[doc(hidden)]
    pub const fn new(
        _private: Private,
        getter: unsafe extern "C" fn(msg: RawMessage) -> T,
        setter: unsafe extern "C" fn(msg: RawMessage, val: T),
        clearer: unsafe extern "C" fn(msg: RawMessage),
        default: T,
    ) -> Self {
        Self { base: PrimitiveVTable { getter, setter }, clearer, default }
    }
}

macro_rules! impl_raw_vtable_mutator_get_set {
  ($($t:ty),*) => {
      $(
          impl RawVTableMutator<'_, $t> {
              pub(crate) fn get(self) -> $t {
                  // SAFETY:
                  // - `msg_ref` is valid for the lifetime of `RawVTableMutator` as promised by the
                  //   caller of `new`.
                  unsafe { (self.vtable.getter)(self.msg_ref.msg()) }
              }

              /// # Safety
              /// - `msg_ref` must be valid for the lifetime of `RawVTableMutator`.
              pub(crate) unsafe fn set(self, val: $t) {
                // SAFETY:
                // - `msg_ref` is valid for the lifetime of `RawVTableMutator` as promised by the
                //   caller of `new`.
                  unsafe { (self.vtable.setter)(self.msg_ref.msg(), val) }
              }
          }
      )*
  }
}

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

/// A generic thunk vtable for mutating a present `bytes` or `string` field.
#[doc(hidden)]
#[derive(Debug)]
pub struct BytesMutVTable {
    pub(crate) setter: unsafe extern "C" fn(msg: RawMessage, val: PtrAndLen),
    pub(crate) getter: unsafe extern "C" fn(msg: RawMessage) -> PtrAndLen,
}

/// A generic thunk vtable for mutating an `optional` `bytes` or `string` field.
#[derive(Debug)]
pub struct BytesOptionalMutVTable {
    pub(crate) base: BytesMutVTable,
    pub(crate) clearer: unsafe extern "C" fn(msg: RawMessage),
    pub(crate) default: &'static [u8],
}

impl BytesMutVTable {
    #[doc(hidden)]
    pub const fn new(
        _private: Private,
        getter: unsafe extern "C" fn(msg: RawMessage) -> PtrAndLen,
        setter: unsafe extern "C" fn(msg: RawMessage, val: PtrAndLen),
    ) -> Self {
        Self { getter, setter }
    }
}

impl BytesOptionalMutVTable {
    /// # Safety
    /// The `default` value must be UTF-8 if required by
    /// the runtime and this is for a `string` field.
    #[doc(hidden)]
    pub const unsafe fn new(
        _private: Private,
        getter: unsafe extern "C" fn(msg: RawMessage) -> PtrAndLen,
        setter: unsafe extern "C" fn(msg: RawMessage, val: PtrAndLen),
        clearer: unsafe extern "C" fn(msg: RawMessage),
        default: &'static [u8],
    ) -> Self {
        Self { base: BytesMutVTable { getter, setter }, clearer, default }
    }
}

impl<'msg> RawVTableMutator<'msg, [u8]> {
    pub(crate) fn get(self) -> &'msg [u8] {
        // SAFETY:
        // - `msg_ref` is valid for `'msg` as promised by the caller of `new`.
        // - The caller of `BytesMutVTable` promised that the returned `PtrAndLen` is
        //   valid for `'msg`.
        unsafe { (self.vtable.getter)(self.msg_ref.msg()).as_ref() }
    }

    /// # Safety
    /// - `msg_ref` must be valid for `'msg`
    /// - If this is for a `string` field, `val` must be valid UTF-8 if the
    ///   runtime requires it.
    pub(crate) unsafe fn set(self, val: &[u8]) {
        let val = copy_bytes_in_arena_if_needed_by_runtime(self.msg_ref, val);
        // SAFETY:
        // - `msg_ref` is valid for `'msg` as promised by the caller of `new`.
        unsafe { (self.vtable.setter)(self.msg_ref.msg(), val.into()) }
    }

    pub(crate) fn truncate(&self, len: usize) {
        if len == 0 {
            // SAFETY: The empty string is valid UTF-8.
            unsafe {
                self.set(b"");
            }
            return;
        }
        todo!("b/294252563")
    }
}

impl<'msg> RawVTableOptionalMutatorData<'msg, [u8]> {
    /// Sets an absent `bytes`/`string` field to its default value.
    pub(crate) fn set_absent_to_default(self) -> Self {
        // SAFETY: The default value is UTF-8 if required by the
        // runtime as promised by the caller of `BytesOptionalMutVTable::new`.
        unsafe { self.set(self.vtable.default) }
    }

    /// # Safety
    /// - If this is a `string` field, `val` must be valid UTF-8 if required by
    ///   the runtime.
    pub(crate) unsafe fn set(self, val: &[u8]) -> Self {
        let val = copy_bytes_in_arena_if_needed_by_runtime(self.msg_ref, val);
        // SAFETY:
        // - `msg_ref` is valid for `'msg` as promised by the caller.
        unsafe { (self.vtable.base.setter)(self.msg_ref.msg(), val.into()) }
        self
    }

    pub(crate) fn clear(self) -> Self {
        // SAFETY:
        // - `msg_ref` is valid for `'msg` as promised by the caller.
        // - The caller of `new` promised that the returned `PtrAndLen` is valid for
        //   `'msg`.
        unsafe { (self.vtable.clearer)(self.msg_ref.msg()) }
        self
    }
}

macro_rules! impl_raw_vtable_optional_mutator_data {
  ($($t:ty),*) => {
      $(
          impl<'msg> RawVTableOptionalMutatorData<'msg, $t> {
              pub(crate) fn set_absent_to_default(self) -> Self {
                // SAFETY:
                // - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as
                //   promised by the caller of `new`.
                self.set(self.vtable.default)
              }

              pub(crate) fn set(self, val: $t) -> Self {
                // SAFETY:
                // - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as
                //   promised by the caller of `new`.
                unsafe { (self.vtable.base.setter)(self.msg_ref.msg(), val.into()) }
                self
              }

              pub(crate) fn clear(self) -> Self {
                // SAFETY:
                // - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as
                //   promised by the caller of `new`.
                unsafe { (self.vtable.clearer)(self.msg_ref.msg()) }
                self
              }
          }
      )*
  }
}

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