use crate::cell::{Cell, UnsafeCell};
use crate::mem::MaybeUninit;
use crate::ptr;
use crate::sys::thread_local::{abort_on_dtor_unwind, destructors};

pub unsafe trait DestroyedState: Sized + Copy {
    fn register_dtor<T>(s: &Storage<T, Self>);
}

unsafe impl DestroyedState for ! {
    fn register_dtor<T>(_: &Storage<T, !>) {}
}

unsafe impl DestroyedState for () {
    fn register_dtor<T>(s: &Storage<T, ()>) {
        unsafe {
            destructors::register(ptr::from_ref(s).cast_mut().cast(), destroy::<T>);
        }
    }
}

#[derive(Copy, Clone)]
enum State<D> {
    Uninitialized,
    Alive,
    Destroyed(D),
}

#[allow(missing_debug_implementations)]
#[repr(C)]
pub struct Storage<T, D> {
    // This field must be first, for correctness of `#[rustc_align_static]`
    value: UnsafeCell<MaybeUninit<T>>,
    state: Cell<State<D>>,
}

impl<T, D> Storage<T, D>
where
    D: DestroyedState,
{
    pub const fn new() -> Storage<T, D> {
        Storage {
            state: Cell::new(State::Uninitialized),
            value: UnsafeCell::new(MaybeUninit::uninit()),
        }
    }

    /// Gets a pointer to the TLS value, potentially initializing it with the
    /// provided parameters. If the TLS variable has been destroyed, a null
    /// pointer is returned.
    ///
    /// The resulting pointer may not be used after reentrant inialialization
    /// or thread destruction has occurred.
    ///
    /// # Safety
    /// The `self` reference must remain valid until the TLS destructor is run.
    #[inline]
    pub unsafe fn get_or_init(&self, i: Option<&mut Option<T>>, f: impl FnOnce() -> T) -> *const T {
        if let State::Alive = self.state.get() {
            self.value.get().cast()
        } else {
            unsafe { self.get_or_init_slow(i, f) }
        }
    }

    /// # Safety
    /// The `self` reference must remain valid until the TLS destructor is run.
    #[cold]
    unsafe fn get_or_init_slow(
        &self,
        i: Option<&mut Option<T>>,
        f: impl FnOnce() -> T,
    ) -> *const T {
        match self.state.get() {
            State::Uninitialized => {}
            State::Alive => return self.value.get().cast(),
            State::Destroyed(_) => return ptr::null(),
        }

        let v = i.and_then(Option::take).unwrap_or_else(f);

        // SAFETY: we cannot be inside a `LocalKey::with` scope, as the initializer
        // has already returned and the next scope only starts after we return
        // the pointer. Therefore, there can be no references to the old value,
        // even if it was initialized. Thus because we are !Sync we have exclusive
        // access to self.value and may replace it.
        let mut old_value = unsafe { self.value.get().replace(MaybeUninit::new(v)) };
        match self.state.replace(State::Alive) {
            // If the variable is not being recursively initialized, register
            // the destructor. This might be a noop if the value does not need
            // destruction.
            State::Uninitialized => D::register_dtor(self),

            // Recursive initialization, we only need to drop the old value
            // as we've already registered the destructor.
            State::Alive => unsafe { old_value.assume_init_drop() },

            State::Destroyed(_) => unreachable!(),
        }

        self.value.get().cast()
    }
}

/// Transition an `Alive` TLS variable into the `Destroyed` state, dropping its
/// value.
///
/// # Safety
/// * Must only be called at thread destruction.
/// * `ptr` must point to an instance of `Storage<T, ()>` and be valid for
///   accessing that instance.
unsafe extern "C" fn destroy<T>(ptr: *mut u8) {
    // Print a nice abort message if a panic occurs.
    abort_on_dtor_unwind(|| {
        let storage = unsafe { &*(ptr as *const Storage<T, ()>) };
        if let State::Alive = storage.state.replace(State::Destroyed(())) {
            // SAFETY: we ensured the state was Alive so the value was initialized.
            // We also updated the state to Destroyed to prevent the destructor
            // from accessing the thread-local variable, as this would violate
            // the exclusive access provided by &mut T in Drop::drop.
            unsafe { (*storage.value.get()).assume_init_drop() }
        }
    })
}
