use crate::stable_hasher::{HashStable, StableHasher};
use crate::sync::{MappedReadGuard, MappedWriteGuard, ReadGuard, RwLock, WriteGuard};

/// The `Steal` struct is intended to used as the value for a query.
/// Specifically, we sometimes have queries (*cough* MIR *cough*)
/// where we create a large, complex value that we want to iteratively
/// update (e.g., optimize). We could clone the value for each
/// optimization, but that'd be expensive. And yet we don't just want
/// to mutate it in place, because that would spoil the idea that
/// queries are these pure functions that produce an immutable value
/// (since if you did the query twice, you could observe the mutations).
/// So instead we have the query produce a `&'tcx Steal<mir::Body<'tcx>>`
/// (to be very specific). Now we can read from this
/// as much as we want (using `borrow()`), but you can also
/// `steal()`. Once you steal, any further attempt to read will panic.
/// Therefore, we know that -- assuming no ICE -- nobody is observing
/// the fact that the MIR was updated.
///
/// Obviously, whenever you have a query that yields a `Steal` value,
/// you must treat it with caution, and make sure that you know that
/// -- once the value is stolen -- it will never be read from again.
//
// FIXME(#41710): what is the best way to model linear queries?
#[derive(Debug)]
pub struct Steal<T> {
    value: RwLock<Option<T>>,
}

impl<T> Steal<T> {
    pub fn new(value: T) -> Self {
        Steal { value: RwLock::new(Some(value)) }
    }

    #[track_caller]
    pub fn borrow(&self) -> MappedReadGuard<'_, T> {
        let borrow = self.value.borrow();
        if borrow.is_none() {
            panic!("attempted to read from stolen value: {}", std::any::type_name::<T>());
        }
        ReadGuard::map(borrow, |opt| opt.as_ref().unwrap())
    }

    /// An escape hatch for rustc drivers to mutate `Steal` caches.
    ///
    /// Use at your own risk. This can badly break incremental compilation
    /// and anything else that relies on the immutability of query caches.
    #[track_caller]
    pub fn risky_hack_borrow_mut(&self) -> MappedWriteGuard<'_, T> {
        let borrow = self.value.borrow_mut();
        if borrow.is_none() {
            panic!("attempted to read from stolen value: {}", std::any::type_name::<T>());
        }
        WriteGuard::map(borrow, |opt| opt.as_mut().unwrap())
    }

    #[track_caller]
    pub fn steal(&self) -> T {
        let value_ref = &mut *self.value.try_write().expect("stealing value which is locked");
        let value = value_ref.take();
        value.expect("attempt to steal from stolen value")
    }

    /// Writers of rustc drivers often encounter stealing issues. This function makes it possible to
    /// handle these errors gracefully.
    ///
    /// This should not be used within rustc as it leaks information not tracked
    /// by the query system, breaking incremental compilation.
    #[rustc_lint_untracked_query_information]
    pub fn is_stolen(&self) -> bool {
        self.value.borrow().is_none()
    }
}

impl<CTX, T: HashStable<CTX>> HashStable<CTX> for Steal<T> {
    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
        self.borrow().hash_stable(hcx, hasher);
    }
}
