#![deny(unsafe_code)]

//! Abstracting over accessing parts of stored value.
//!
//! Sometimes, there's a big globalish data structure (like a configuration for the whole program).
//! Then there are parts of the program that need access to up-to-date version of their *part* of
//! the configuration, but for reasons of code separation and reusability, it is not desirable to
//! pass the whole configuration to each of the parts.
//!
//! This module provides means to grant the parts access to the relevant subsets of such global
//! data structure while masking the fact it is part of the bigger whole from the component.
//!
//! Note that the [`cache`][crate::cache] module has its own [`Access`][crate::cache::Access] trait
//! that serves a similar purpose, but with cached access. The signatures are different, therefore
//! an incompatible trait.
//!
//! # The general idea
//!
//! Each part of the code accepts generic [`Access<T>`][Access] for the `T` of its interest. This
//! provides means to load current version of the structure behind the scenes and get only the
//! relevant part, without knowing what the big structure is.
//!
//! For technical reasons, the [`Access`] trait is not object safe. If type erasure is desired, it
//! is possible use the [`DynAccess`][crate::access::DynAccess] instead, which is object safe, but
//! slightly slower.
//!
//! For some cases, it is possible to use [`ArcSwapAny::map`]. If that is not flexible enough, the
//! [`Map`] type can be created directly.
//!
//! Note that the [`Access`] trait is also implemented for [`ArcSwapAny`] itself. Additionally,
//! there's the [`Constant`][crate::access::Constant] helper type, which is useful mostly for
//! testing (it doesn't allow reloading).
//!
//! # Performance
//!
//! In general, these utilities use [`ArcSwapAny::load`] internally and then apply the provided
//! transformation. This has several consequences:
//!
//! * Limitations of the [`load`][ArcSwapAny::load] apply ‒ including the recommendation to not
//!   hold the returned guard object for too long, but long enough to get consistency.
//! * The transformation should be cheap ‒ optimally just borrowing into the structure.
//!
//! # Examples
//!
//! ```rust
//! use std::sync::Arc;
//! use std::thread::{self, JoinHandle};
//! use std::time::Duration;
//!
//! use arc_swap::ArcSwap;
//! use arc_swap::access::{Access, Constant, Map};
//!
//! fn work_with_usize<A: Access<usize> + Send + 'static>(a: A) -> JoinHandle<()> {
//!     thread::spawn(move || {
//!         let mut value = 0;
//!         while value != 42 {
//!             let guard = a.load();
//!             value = *guard;
//!             println!("{}", value);
//!             // Not strictly necessary, but dropping the guard can free some resources, like
//!             // slots for tracking what values are still in use. We do it before the sleeping,
//!             // not at the end of the scope.
//!             drop(guard);
//!             thread::sleep(Duration::from_millis(50));
//!         }
//!     })
//! }
//!
//! // Passing the whole thing directly
//! // (If we kept another Arc to it, we could change the value behind the scenes)
//! work_with_usize(Arc::new(ArcSwap::from_pointee(42))).join().unwrap();
//!
//! // Passing a subset of a structure
//! struct Cfg {
//!     value: usize,
//! }
//!
//! let cfg = Arc::new(ArcSwap::from_pointee(Cfg { value: 0 }));
//! let thread = work_with_usize(Map::new(Arc::clone(&cfg), |cfg: &Cfg| &cfg.value));
//! cfg.store(Arc::new(Cfg { value: 42 }));
//! thread.join().unwrap();
//!
//! // Passing a constant that can't change. Useful mostly for testing purposes.
//! work_with_usize(Constant(42)).join().unwrap();
//! ```
use core::marker::PhantomData;
use core::ops::Deref;

use alloc::boxed::Box;
use alloc::rc::Rc;
use alloc::sync::Arc;

use super::ref_cnt::RefCnt;
use super::strategy::Strategy;
use super::{ArcSwapAny, Guard};

/// Abstracts over ways code can get access to a value of type `T`.
///
/// This is the trait that parts of code will use when accessing a subpart of the big data
/// structure. See the [module documentation](index.html) for details.
pub trait Access<T> {
    /// A guard object containing the value and keeping it alive.
    ///
    /// For technical reasons, the library doesn't allow direct access into the stored value. A
    /// temporary guard object must be loaded, that keeps the actual value alive for the time of
    /// use.
    type Guard: Deref<Target = T>;

    /// The loading method.
    ///
    /// This returns the guard that holds the actual value. Should be called anew each time a fresh
    /// value is needed.
    fn load(&self) -> Self::Guard;
}

impl<T, A: Access<T> + ?Sized, P: Deref<Target = A>> Access<T> for P {
    type Guard = A::Guard;
    fn load(&self) -> Self::Guard {
        self.deref().load()
    }
}

impl<T> Access<T> for dyn DynAccess<T> + '_ {
    type Guard = DynGuard<T>;

    fn load(&self) -> Self::Guard {
        self.load()
    }
}

impl<T> Access<T> for dyn DynAccess<T> + '_ + Send {
    type Guard = DynGuard<T>;

    fn load(&self) -> Self::Guard {
        self.load()
    }
}

impl<T> Access<T> for dyn DynAccess<T> + '_ + Sync + Send {
    type Guard = DynGuard<T>;

    fn load(&self) -> Self::Guard {
        self.load()
    }
}

impl<T: RefCnt, S: Strategy<T>> Access<T> for ArcSwapAny<T, S> {
    type Guard = Guard<T, S>;

    fn load(&self) -> Self::Guard {
        self.load()
    }
}

#[derive(Debug)]
#[doc(hidden)]
pub struct DirectDeref<T: RefCnt, S: Strategy<T>>(Guard<T, S>);

impl<T, S: Strategy<Arc<T>>> Deref for DirectDeref<Arc<T>, S> {
    type Target = T;
    fn deref(&self) -> &T {
        self.0.deref().deref()
    }
}

impl<T, S: Strategy<Arc<T>>> Access<T> for ArcSwapAny<Arc<T>, S> {
    type Guard = DirectDeref<Arc<T>, S>;
    fn load(&self) -> Self::Guard {
        DirectDeref(self.load())
    }
}

impl<T, S: Strategy<Rc<T>>> Deref for DirectDeref<Rc<T>, S> {
    type Target = T;
    fn deref(&self) -> &T {
        self.0.deref().deref()
    }
}

impl<T, S: Strategy<Rc<T>>> Access<T> for ArcSwapAny<Rc<T>, S> {
    type Guard = DirectDeref<Rc<T>, S>;
    fn load(&self) -> Self::Guard {
        DirectDeref(self.load())
    }
}

#[doc(hidden)]
pub struct DynGuard<T: ?Sized>(Box<dyn Deref<Target = T>>);

impl<T: ?Sized> Deref for DynGuard<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

/// An object-safe version of the [`Access`] trait.
///
/// This can be used instead of the [`Access`] trait in case a type erasure is desired. This has
/// the effect of performance hit (due to boxing of the result and due to dynamic dispatch), but
/// makes certain code simpler and possibly makes the executable smaller.
///
/// This is automatically implemented for everything that implements [`Access`].
///
/// # Examples
///
/// ```rust
/// use arc_swap::access::{Constant, DynAccess};
///
/// fn do_something(value: Box<dyn DynAccess<usize> + Send>) {
///     let v = value.load();
///     println!("{}", *v);
/// }
///
/// do_something(Box::new(Constant(42)));
/// ```
pub trait DynAccess<T> {
    /// The equivalent of [`Access::load`].
    fn load(&self) -> DynGuard<T>;
}

impl<T, A> DynAccess<T> for A
where
    A: Access<T>,
    A::Guard: 'static,
{
    fn load(&self) -> DynGuard<T> {
        DynGuard(Box::new(Access::load(self)))
    }
}

/// [DynAccess] to [Access] wrapper.
///
/// In previous versions, `Box<dyn DynAccess>` didn't implement [Access], to use inside [Map] one
/// could use this wrapper. Since then, a way was found to solve it. In most cases, this wrapper is
/// no longer necessary.
///
/// This is left in place for two reasons:
/// * Backwards compatibility.
/// * Corner-cases not covered by the found solution. For example, trait inheritance in the form of
///   `Box<dyn SomeTrait>` where `SomeTrait: Access` doesn't work out of the box and still needs
///   this wrapper.
///
/// # Examples
///
/// The example is for the simple case (which is no longer needed, but may help as an inspiration).
///
/// ```rust
/// use std::sync::Arc;
///
/// use arc_swap::ArcSwap;
/// use arc_swap::access::{AccessConvert, DynAccess, Map};
///
/// struct Inner {
///     val: usize,
/// }
///
/// struct Middle {
///     inner: Inner,
/// }
///
/// struct Outer {
///     middle: Middle,
/// }
///
/// let outer = Arc::new(ArcSwap::from_pointee(Outer {
///     middle: Middle {
///         inner: Inner {
///             val: 42,
///         }
///     }
/// }));
///
/// let middle: Arc<dyn DynAccess<Middle>> =
///     Arc::new(Map::new(outer, |outer: &Outer| &outer.middle));
/// let inner: Arc<dyn DynAccess<Inner>> =
///     Arc::new(Map::new(AccessConvert(middle), |middle: &Middle| &middle.inner));
/// let guard = inner.load();
/// assert_eq!(42, guard.val);
/// ```
pub struct AccessConvert<D>(pub D);

impl<T, D> Access<T> for AccessConvert<D>
where
    D: Deref,
    D::Target: DynAccess<T>,
{
    type Guard = DynGuard<T>;

    fn load(&self) -> Self::Guard {
        self.0.load()
    }
}

#[doc(hidden)]
#[derive(Copy, Clone, Debug)]
pub struct MapGuard<G, F, T, R> {
    guard: G,
    projection: F,
    _t: PhantomData<fn(&T) -> &R>,
}

impl<G, F, T, R> Deref for MapGuard<G, F, T, R>
where
    G: Deref<Target = T>,
    F: Fn(&T) -> &R,
{
    type Target = R;
    fn deref(&self) -> &R {
        (self.projection)(&self.guard)
    }
}

/// An adaptor to provide access to a part of larger structure.
///
/// This is the *active* part of this module. Use the [module documentation](index.html) for the
/// details.
#[derive(Copy, Clone, Debug)]
pub struct Map<A, T, F> {
    access: A,
    projection: F,
    _t: PhantomData<fn() -> T>,
}

impl<A, T, F> Map<A, T, F> {
    /// Creates a new instance.
    ///
    /// # Parameters
    ///
    /// * `access`: Access to the bigger structure. This is usually something like `Arc<ArcSwap>`
    ///   or `&ArcSwap`. It is technically possible to use any other [`Access`] here, though, for
    ///   example to sub-delegate into even smaller structure from a [`Map`] (or generic
    ///   [`Access`]).
    /// * `projection`: A function (or closure) responsible to providing a reference into the
    ///   bigger bigger structure, selecting just subset of it. In general, it is expected to be
    ///   *cheap* (like only taking reference).
    pub fn new<R>(access: A, projection: F) -> Self
    where
        F: Fn(&T) -> &R + Clone,
    {
        Map {
            access,
            projection,
            _t: PhantomData,
        }
    }
}

impl<A, F, T, R> Access<R> for Map<A, T, F>
where
    A: Access<T>,
    F: Fn(&T) -> &R + Clone,
{
    type Guard = MapGuard<A::Guard, F, T, R>;
    fn load(&self) -> Self::Guard {
        let guard = self.access.load();
        MapGuard {
            guard,
            projection: self.projection.clone(),
            _t: PhantomData,
        }
    }
}

#[doc(hidden)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ConstantDeref<T>(T);

impl<T> Deref for ConstantDeref<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

/// Access to an constant.
///
/// This wraps a constant value to provide [`Access`] to it. It is constant in the sense that,
/// unlike [`ArcSwapAny`] and [`Map`], the loaded value will always stay the same (there's no
/// remote `store`).
///
/// The purpose is mostly testing and plugging a parameter that works generically from code that
/// doesn't need the updating functionality.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Constant<T>(pub T);

impl<T: Clone> Access<T> for Constant<T> {
    type Guard = ConstantDeref<T>;
    fn load(&self) -> Self::Guard {
        ConstantDeref(self.0.clone())
    }
}

#[cfg(test)]
mod tests {
    use super::super::{ArcSwap, ArcSwapOption};

    use super::*;

    fn check_static_dispatch_direct<A: Access<usize>>(a: A) {
        assert_eq!(42, *a.load());
    }

    fn check_static_dispatch<A: Access<Arc<usize>>>(a: A) {
        assert_eq!(42, **a.load());
    }

    /// Tests dispatching statically from arc-swap works
    #[test]
    fn static_dispatch() {
        let a = ArcSwap::from_pointee(42);
        check_static_dispatch_direct(&a);
        check_static_dispatch(&a);
        check_static_dispatch(a);
    }

    fn check_dyn_dispatch_direct(a: &dyn DynAccess<usize>) {
        assert_eq!(42, *a.load());
    }

    fn check_dyn_dispatch(a: &dyn DynAccess<Arc<usize>>) {
        assert_eq!(42, **a.load());
    }

    /// Tests we can also do a dynamic dispatch of the companion trait
    #[test]
    fn dyn_dispatch() {
        let a = ArcSwap::from_pointee(42);
        check_dyn_dispatch_direct(&a);
        check_dyn_dispatch(&a);
    }

    fn check_transition<A>(a: A)
    where
        A: Access<usize>,
        A::Guard: 'static,
    {
        check_dyn_dispatch_direct(&a)
    }

    /// Tests we can easily transition from the static dispatch trait to the dynamic one
    #[test]
    fn transition() {
        let a = ArcSwap::from_pointee(42);
        check_transition(&a);
        check_transition(a);
    }

    /// Test we can dispatch from Arc<ArcSwap<_>> or similar.
    #[test]
    fn indirect() {
        let a = Arc::new(ArcSwap::from_pointee(42));
        check_static_dispatch(&a);
        check_dyn_dispatch(&a);
    }

    struct Cfg {
        value: usize,
    }

    #[test]
    fn map() {
        let a = ArcSwap::from_pointee(Cfg { value: 42 });
        let map = a.map(|a: &Cfg| &a.value);
        check_static_dispatch_direct(&map);
        check_dyn_dispatch_direct(&map);
    }

    #[test]
    fn map_option_some() {
        let a = ArcSwapOption::from_pointee(Cfg { value: 42 });
        let map = a.map(|a: &Option<Arc<Cfg>>| a.as_ref().map(|c| &c.value).unwrap());
        check_static_dispatch_direct(&map);
        check_dyn_dispatch_direct(&map);
    }

    #[test]
    fn map_option_none() {
        let a = ArcSwapOption::empty();
        let map = a.map(|a: &Option<Arc<Cfg>>| a.as_ref().map(|c| &c.value).unwrap_or(&42));
        check_static_dispatch_direct(&map);
        check_dyn_dispatch_direct(&map);
    }

    #[test]
    fn constant() {
        let c = Constant(42);
        check_static_dispatch_direct(c);
        check_dyn_dispatch_direct(&c);
        check_static_dispatch_direct(c);
    }

    #[test]
    fn map_reload() {
        let a = ArcSwap::from_pointee(Cfg { value: 0 });
        let map = a.map(|cfg: &Cfg| &cfg.value);
        assert_eq!(0, *Access::load(&map));
        a.store(Arc::new(Cfg { value: 42 }));
        assert_eq!(42, *Access::load(&map));
    }

    // Compile tests for dynamic access
    fn _expect_access<T>(_: impl Access<T>) {}

    fn _dyn_access<T>(x: Box<dyn DynAccess<T> + '_>) {
        _expect_access(x)
    }

    fn _dyn_access_send<T>(x: Box<dyn DynAccess<T> + '_ + Send>) {
        _expect_access(x)
    }

    fn _dyn_access_send_sync<T>(x: Box<dyn DynAccess<T> + '_ + Send + Sync>) {
        _expect_access(x)
    }

    #[test]
    #[allow(clippy::arc_with_non_send_sync)] // Whatever, it's tests...
    fn double_dyn_access_complex() {
        struct Inner {
            val: usize,
        }

        struct Middle {
            inner: Inner,
        }

        struct Outer {
            middle: Middle,
        }

        let outer = Arc::new(ArcSwap::from_pointee(Outer {
            middle: Middle {
                inner: Inner { val: 42 },
            },
        }));

        let middle: Arc<dyn DynAccess<Middle>> =
            Arc::new(Map::new(outer, |outer: &Outer| &outer.middle));
        let inner: Arc<dyn DynAccess<Inner>> =
            Arc::new(Map::new(middle, |middle: &Middle| &middle.inner));
        // Damn. We have the DynAccess wrapper in scope and need to disambiguate the inner.load()
        let guard = Access::load(&inner);
        assert_eq!(42, guard.val);
    }
}
