// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Explicit stack slots, which can be used for stack emplacement.
//!
//! A [`Slot`] is uninitialized storage on the stack that can be manipulated
//! explicitly. Notionally, a [`Slot<T>`] represents a `let x: T;` in some
//! function's stack.
//!
//! [`Slot`]s mut be created with the [`slot!()`] macro:
//! ```
//! # use moveit::{slot};
//! slot!(storage);
//! let mut x = storage.put(42);
//! *x /= 2;
//! assert_eq!(*x, 21);
//! ```
//! Unfortunately, due to the constrains of Rust today, it is not possible to
//! produce a [`Slot`] as part of a larger expression; since it needs to expand
//! to a `let` to bind the stack location, [`slot!()`] must be a statement, not
//! an expression.
//!
//! [`Slot`]s can also be used to implement a sort of "guaranteed RVO":
//! ```
//! # use moveit::{slot, Slot, move_ref::MoveRef};
//! fn returns_on_the_stack(val: i32, storage: Slot<i32>) -> Option<MoveRef<i32>> {
//!   if val == 0 {
//!     return None
//!   }
//!   Some(storage.put(val))
//! }
//!
//! slot!(storage);
//! let val = returns_on_the_stack(42, storage);
//! assert_eq!(*val.unwrap(), 42);
//! ```
//!
//! [`Slot`]s provide a natural location for emplacing values on the stack.
//! The [`moveit!()`] macro is intended to make this operation
//! straight-forward.
//!
//! # [`DroppingSlot`]
//!
//! [`DroppingSlot`] is a support type similar to [`Slot`] that is used for
//! implementing [`DerefMove`], but which users should otherwise not construct
//! themselves (despite it being otherwise perfectly safe to do so).

use core::mem;
use core::mem::MaybeUninit;
use core::pin::Pin;
use core::ptr;

use crate::drop_flag::DropFlag;
use crate::move_ref::MoveRef;
use crate::new;
use crate::new::New;
use crate::new::TryNew;

#[cfg(doc)]
use {
  crate::{move_ref::DerefMove, moveit, slot},
  alloc::boxed::Box,
};

/// An empty slot on the stack into which a value could be emplaced.
///
/// The `'frame` lifetime refers to the lifetime of the stack frame this
/// `Slot`'s storage is allocated on.
///
/// See [`slot!()`] and [the module documentation][self].
pub struct Slot<'frame, T> {
  ptr: &'frame mut MaybeUninit<T>,
  drop_flag: DropFlag<'frame>,
}

impl<'frame, T> Slot<'frame, T> {
  /// Creates a new `Slot` with the given pointer as its basis.
  ///
  /// To safely construct a `Slot`, use [`slot!()`].
  ///
  /// # Safety
  ///
  /// `ptr` must not be outlived by any other pointers to its allocation.
  ///
  /// `drop_flag`'s value must be dead, and must be a drop flag governing
  /// the destruction of `ptr`'s storage in an appropriate manner as described
  /// in [`moveit::drop_flag`][crate::drop_flag].
  pub unsafe fn new_unchecked(
    ptr: &'frame mut MaybeUninit<T>,
    drop_flag: DropFlag<'frame>,
  ) -> Self {
    Self { ptr, drop_flag }
  }

  /// Put `val` into this slot, returning a new [`MoveRef`].
  pub fn put(self, val: T) -> MoveRef<'frame, T> {
    unsafe {
      // SAFETY: Pinning is conserved by this operation.
      Pin::into_inner_unchecked(self.pin(val))
    }
  }

  /// Pin `val` into this slot, returning a new, pinned [`MoveRef`].
  pub fn pin(self, val: T) -> Pin<MoveRef<'frame, T>> {
    self.emplace(new::of(val))
  }

  /// Emplace `new` into this slot, returning a new, pinned [`MoveRef`].
  pub fn emplace<N: New<Output = T>>(self, new: N) -> Pin<MoveRef<'frame, T>> {
    match self.try_emplace(new) {
      Ok(x) => x,
      Err(e) => match e {},
    }
  }

  /// Try to emplace `new` into this slot, returning a new, pinned [`MoveRef`].
  pub fn try_emplace<N: TryNew<Output = T>>(
    self,
    new: N,
  ) -> Result<Pin<MoveRef<'frame, T>>, N::Error> {
    unsafe {
      self.drop_flag.inc();
      new.try_new(Pin::new_unchecked(self.ptr))?;
      Ok(MoveRef::into_pin(MoveRef::new_unchecked(
        self.ptr.assume_init_mut(),
        self.drop_flag,
      )))
    }
  }

  /// Converts this into a slot for a pinned `T`.
  ///
  /// This is safe, since this `Slot` owns the referenced data, and
  /// `Pin` is explicitly a `repr(transparent)` type.
  pub fn into_pinned(self) -> Slot<'frame, Pin<T>> {
    unsafe { self.cast() }
  }

  /// Converts this `Slot` from being a slot for a `T` to being a slot for
  /// some other type `U`.
  ///
  /// ```
  /// # use moveit::{Slot, MoveRef};
  /// moveit::slot!(place: u32);
  /// let foo: MoveRef<u16> = unsafe { place.cast::<u16>() }.put(42);
  /// ```
  ///
  /// # Safety
  ///
  /// `T` must have at least the size and alignment as `U`.
  pub unsafe fn cast<U>(self) -> Slot<'frame, U> {
    debug_assert!(mem::size_of::<T>() >= mem::size_of::<U>());
    debug_assert!(mem::align_of::<T>() >= mem::align_of::<U>());
    Slot {
      ptr: &mut *self.ptr.as_mut_ptr().cast(),
      drop_flag: self.drop_flag,
    }
  }
}

impl<'frame, T> Slot<'frame, Pin<T>> {
  /// Converts this into a slot for an unpinned `T`.
  ///
  /// This is safe, since this `Slot` owns the referenced data, and
  /// `Pin` is explicitly a `repr(transparent)` type.
  ///
  /// Moreover, no actual unpinning is occurring: the referenced data must
  /// be uninitialized, so it cannot have a pinned referent.
  pub fn into_unpinned(self) -> Slot<'frame, T> {
    unsafe { self.cast() }
  }
}

/// Similar to a [`Slot`], but able to drop its contents.
///
/// A `DroppingSlot` wraps a [`Slot`], and will drop its contents if the
/// [`Slot`]'s drop flag is dead at the time of the `DroppingSlot`'s
/// destruction.
///
/// This type has an API similar to [`Slot`]'s, but rather than returning
/// `MoveRef`s, which would own the contents of this slot, we return a `&mut T`
/// and a [`DropFlag`], which the caller can assemble into an
/// appropriately-shaped `MoveRef`. The drop flag will be one decrement away
/// from being dead; callers should make sure to decremement it to trigger
/// destruction.
///
/// `DroppingSlot` is intended to be used with [`DerefMove::deref_move()`],
/// and will usually not be created by `moveit`'s users. However, [`slot!()`]
/// provides `DroppingSlot` support, too. These slots will silently forget their
/// contents if the drop flag is left untouched, rather than crash.
pub struct DroppingSlot<'frame, T> {
  ptr: &'frame mut MaybeUninit<T>,
  drop_flag: DropFlag<'frame>,
}

impl<'frame, T> DroppingSlot<'frame, T> {
  /// Creates a new `DroppingSlot` with the given pointer as its basis.
  ///
  /// To safely construct a `DroppingSlot`, use [`slot!()`].
  ///
  /// # Safety
  ///
  /// `ptr` must not be outlived by any other pointers to its allocation.
  ///
  /// `drop_flag`'s value must be dead, and must be a drop flag governing
  /// the destruction of `ptr`'s storage in an appropriate manner as described
  /// in [`moveit::drop_flag`][crate::drop_flag].
  pub unsafe fn new_unchecked(
    ptr: &'frame mut MaybeUninit<T>,
    drop_flag: DropFlag<'frame>,
  ) -> Self {
    drop_flag.inc();
    Self { ptr, drop_flag }
  }

  /// Put `val` into this slot, returning a reference to it.
  pub fn put(self, val: T) -> (&'frame mut T, DropFlag<'frame>) {
    ({ self.ptr }.write(val), self.drop_flag)
  }

  /// Pin `val` into this slot, returning a reference to it.
  ///
  /// # Safety
  ///
  /// This function pins the memory this slot wraps, but does not guarantee its
  /// destructor is run; that is the caller's responsibility, by decrementing
  /// the given [`DropFlag`].
  pub unsafe fn pin(self, val: T) -> (Pin<&'frame mut T>, DropFlag<'frame>) {
    self.emplace(new::of(val))
  }

  /// Emplace `new` into this slot, returning a reference to it.
  ///
  /// # Safety
  ///
  /// This function pins the memory this slot wraps, but does not guarantee its
  /// destructor is run; that is the caller's responsibility, by decrementing
  /// the given [`DropFlag`].
  pub unsafe fn emplace<N: New<Output = T>>(
    self,
    new: N,
  ) -> (Pin<&'frame mut T>, DropFlag<'frame>) {
    match self.try_emplace(new) {
      Ok((x, d)) => (x, d),
      Err(e) => match e {},
    }
  }

  /// Try to emplace `new` into this slot, returning a reference to it.
  ///
  /// # Safety
  ///
  /// This function pins the memory this slot wraps, but does not guarantee its
  /// destructor is run; that is the caller's responsibility, by decrementing
  /// the given [`DropFlag`].
  pub unsafe fn try_emplace<N: TryNew<Output = T>>(
    self,
    new: N,
  ) -> Result<(Pin<&'frame mut T>, DropFlag<'frame>), N::Error> {
    self.drop_flag.inc();
    new.try_new(Pin::new_unchecked(self.ptr))?;
    Ok((
      Pin::new_unchecked(self.ptr.assume_init_mut()),
      self.drop_flag,
    ))
  }
}

#[doc(hidden)]
#[allow(missing_docs)]
pub mod __macro {
  use super::*;
  use crate::drop_flag::QuietFlag;
  pub use core;

  pub struct SlotDropper<T> {
    val: MaybeUninit<T>,
    drop_flag: QuietFlag,
  }

  impl<T> SlotDropper<T> {
    #[allow(clippy::new_without_default)]
    pub fn new() -> Self {
      Self {
        val: MaybeUninit::uninit(),
        drop_flag: QuietFlag::new(),
      }
    }

    // Workaround for `unsafe {}` unhygine wrt to lints.
    //
    // This function is still `unsafe`.
    pub fn new_unchecked_hygine_hack(&mut self) -> DroppingSlot<T> {
      unsafe {
        DroppingSlot::new_unchecked(&mut self.val, self.drop_flag.flag())
      }
    }
  }

  impl<T> Drop for SlotDropper<T> {
    fn drop(&mut self) {
      if self.drop_flag.flag().is_dead() {
        unsafe { ptr::drop_in_place(self.val.assume_init_mut()) }
      }
    }
  }

  // Workaround for `unsafe {}` unhygine wrt to lints.
  //
  // This function is still `unsafe`.
  pub fn new_unchecked_hygine_hack<'frame, T>(
    ptr: &'frame mut MaybeUninit<T>,
    drop_flag: DropFlag<'frame>,
  ) -> Slot<'frame, T> {
    unsafe { Slot::new_unchecked(ptr, drop_flag) }
  }
}

/// Constructs a new [`Slot`].
///
/// Because [`Slot`]s need to own data on the stack, but that data cannot
/// move with the [`Slot`], it must be constructed using this macro. For
/// example:
/// ```
/// moveit::slot!(x, y: bool);
/// let x = x.put(5);
/// let y = y.put(false);
/// ```
///
/// This macro is especially useful for passing data into functions that want to
/// emplace a value into the caller.
///
/// The `slot!(#[dropping] x)` syntax can be used to create a [`DroppingSlot`]
/// instead. This should be a comparatively rare operation.
///
/// This macro can also be used without arguments to create a *temporary*
/// [`Slot`]. Such types cannot be assigned to variables but can be used as
/// part of a larger expression:
///
/// ```compile_fail
/// # use moveit::Slot;
/// let bad: Slot<i32> = moveit::slot!();
/// bad.put(4);  // Borrow check error.
/// ```
///
/// ```
/// # use moveit::Slot;
/// fn do_thing(x: Slot<i32>) { /* ... */ }
/// do_thing(moveit::slot!())
/// ```
#[macro_export]
macro_rules! slot {
  () => {
    $crate::slot::__macro::new_unchecked_hygine_hack(
      &mut $crate::slot::__macro::core::mem::MaybeUninit::uninit(),
      $crate::drop_flag::TrappedFlag::new().flag(),
    )
  };
  (#[dropping]) => {
    $crate::slot::__macro::SlotDropper::new().new_unchecked_hygine_hack()
  };
  ($($name:ident $(: $ty:ty)?),* $(,)*) => {$(
    let mut uninit = $crate::slot::__macro::core::mem::MaybeUninit::<
      $crate::slot!(@tyof $($ty)?)
    >::uninit();let trap = $crate::drop_flag::TrappedFlag::new();
    let $name = $crate::slot::__macro::new_unchecked_hygine_hack(
      &mut uninit,
      trap.flag()
    );
  )*};
  (#[dropping] $($name:ident $(: $ty:ty)?),* $(,)*) => {$(
    let mut uninit = $crate::slot::__macro::SlotDropper::<
      $crate::slot!(@tyof $($ty)?)
    >::new();
    #[allow(unsafe_code, unused_unsafe)]
    let $name = uninit.new_unchecked_hygine_hack();
  )*};
  (@tyof) => {_};
  (@tyof $ty:ty) => {$ty};
}
