// SPDX-License-Identifier: Apache-2.0 OR MIT

#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::{boxed::Box, sync::Arc};
#[cfg(feature = "alloc")]
use core::alloc::AllocError;
use core::{mem::MaybeUninit, pin::Pin};
#[cfg(feature = "std")]
use std::sync::Arc;

#[cfg(not(feature = "alloc"))]
type AllocError = core::convert::Infallible;

use crate::{
    init_from_closure, pin_init_from_closure, InPlaceWrite, Init, PinInit, ZeroableOption,
};

pub extern crate alloc;

// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee).
//
// In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant and there
// is no problem with a VTABLE pointer being null.
unsafe impl<T: ?Sized> ZeroableOption for Box<T> {}

/// Smart pointer that can initialize memory in-place.
pub trait InPlaceInit<T>: Sized {
    /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
    /// type.
    ///
    /// If `T: !Unpin` it will not be able to move afterwards.
    fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
    where
        E: From<AllocError>;

    /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
    /// type.
    ///
    /// If `T: !Unpin` it will not be able to move afterwards.
    fn pin_init(init: impl PinInit<T>) -> Result<Pin<Self>, AllocError> {
        // SAFETY: We delegate to `init` and only change the error type.
        let init = unsafe {
            pin_init_from_closure(|slot| match init.__pinned_init(slot) {
                Ok(()) => Ok(()),
                Err(i) => match i {},
            })
        };
        Self::try_pin_init(init)
    }

    /// Use the given initializer to in-place initialize a `T`.
    fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
    where
        E: From<AllocError>;

    /// Use the given initializer to in-place initialize a `T`.
    fn init(init: impl Init<T>) -> Result<Self, AllocError> {
        // SAFETY: We delegate to `init` and only change the error type.
        let init = unsafe {
            init_from_closure(|slot| match init.__init(slot) {
                Ok(()) => Ok(()),
                Err(i) => match i {},
            })
        };
        Self::try_init(init)
    }
}

#[cfg(feature = "alloc")]
macro_rules! try_new_uninit {
    ($type:ident) => {
        $type::try_new_uninit()?
    };
}
#[cfg(all(feature = "std", not(feature = "alloc")))]
macro_rules! try_new_uninit {
    ($type:ident) => {
        $type::new_uninit()
    };
}

impl<T> InPlaceInit<T> for Box<T> {
    #[inline]
    fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
    where
        E: From<AllocError>,
    {
        try_new_uninit!(Box).write_pin_init(init)
    }

    #[inline]
    fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
    where
        E: From<AllocError>,
    {
        try_new_uninit!(Box).write_init(init)
    }
}

impl<T> InPlaceInit<T> for Arc<T> {
    #[inline]
    fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
    where
        E: From<AllocError>,
    {
        let mut this = try_new_uninit!(Arc);
        let Some(slot) = Arc::get_mut(&mut this) else {
            // SAFETY: the Arc has just been created and has no external references
            unsafe { core::hint::unreachable_unchecked() }
        };
        let slot = slot.as_mut_ptr();
        // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
        // slot is valid and will not be moved, because we pin it later.
        unsafe { init.__pinned_init(slot)? };
        // SAFETY: All fields have been initialized and this is the only `Arc` to that data.
        Ok(unsafe { Pin::new_unchecked(this.assume_init()) })
    }

    #[inline]
    fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
    where
        E: From<AllocError>,
    {
        let mut this = try_new_uninit!(Arc);
        let Some(slot) = Arc::get_mut(&mut this) else {
            // SAFETY: the Arc has just been created and has no external references
            unsafe { core::hint::unreachable_unchecked() }
        };
        let slot = slot.as_mut_ptr();
        // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
        // slot is valid.
        unsafe { init.__init(slot)? };
        // SAFETY: All fields have been initialized.
        Ok(unsafe { this.assume_init() })
    }
}

impl<T> InPlaceWrite<T> for Box<MaybeUninit<T>> {
    type Initialized = Box<T>;

    fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> {
        let slot = self.as_mut_ptr();
        // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
        // slot is valid.
        unsafe { init.__init(slot)? };
        // SAFETY: All fields have been initialized.
        Ok(unsafe { self.assume_init() })
    }

    fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> {
        let slot = self.as_mut_ptr();
        // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
        // slot is valid and will not be moved, because we pin it later.
        unsafe { init.__pinned_init(slot)? };
        // SAFETY: All fields have been initialized.
        Ok(unsafe { self.assume_init() }.into())
    }
}
