#![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 std::marker::PhantomData;
use std::ops::Deref;
use std::rc::Rc;
use std::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]
    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);
    }
}
