//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SynchronizedValue.h:
//   A class that ensures that the correct mutex is locked when the encapsulated data is accessed.
//   Based on boost::synchronized_value, which probably becomes part of the next C++ standard.
// https://www.boost.org/doc/libs/1_76_0/doc/html/thread/sds.html#thread.sds.synchronized_valuesxxx

#ifndef COMMON_SYNCHRONIZEDVALUE_H_
#define COMMON_SYNCHRONIZEDVALUE_H_

#include "common/debug.h"

#include <mutex>
#include <type_traits>

namespace angle
{

template <typename T, typename Lockable = std::mutex>
class ConstStrictLockPtr
{
  public:
    using value_type = T;
    using mutex_type = Lockable;

    ConstStrictLockPtr(const T &value, Lockable &mutex) : mLock(mutex), mValue(value) {}
    ConstStrictLockPtr(const T &value, Lockable &mutex, std::adopt_lock_t) noexcept
        : mLock(mutex, std::adopt_lock), mValue(value)
    {}

    ConstStrictLockPtr(ConstStrictLockPtr &&other) noexcept
        : mLock(std::move(other.mLock)), mValue(other.mValue)
    {}

    ConstStrictLockPtr(const ConstStrictLockPtr &) = delete;
    ConstStrictLockPtr &operator=(const ConstStrictLockPtr &) = delete;

    ~ConstStrictLockPtr() = default;

    const T *operator->() const { return &mValue; }
    const T &operator*() const { return mValue; }

  protected:
    std::unique_lock<Lockable> mLock;
    T const &mValue;
};

template <typename T, typename Lockable = std::mutex>
class StrictLockPtr : public ConstStrictLockPtr<T, Lockable>
{
  private:
    using BaseType = ConstStrictLockPtr<T, Lockable>;

  public:
    StrictLockPtr(T &value, Lockable &mutex) : BaseType(value, mutex) {}
    StrictLockPtr(T &value, Lockable &mutex, std::adopt_lock_t) noexcept
        : BaseType(value, mutex, std::adopt_lock)
    {}

    StrictLockPtr(StrictLockPtr &&other) noexcept
        : BaseType(std::move(static_cast<BaseType &&>(other)))
    {}

    StrictLockPtr(const StrictLockPtr &) = delete;
    StrictLockPtr &operator=(const StrictLockPtr &) = delete;

    ~StrictLockPtr() = default;

    T *operator->() { return const_cast<T *>(&this->mValue); }
    T &operator*() { return const_cast<T &>(this->mValue); }
};

template <typename SV>
struct SynchronizedValueStrictLockPtr
{
    using type = StrictLockPtr<typename SV::value_type, typename SV::mutex_type>;
};

template <typename SV>
struct SynchronizedValueStrictLockPtr<const SV>
{
    using type = ConstStrictLockPtr<typename SV::value_type, typename SV::mutex_type>;
};

template <typename T, typename Lockable = std::mutex>
class ConstUniqueLockPtr : public std::unique_lock<Lockable>
{
  private:
    using BaseType = std::unique_lock<Lockable>;

  public:
    using value_type = T;
    using mutex_type = Lockable;

    ConstUniqueLockPtr(const T &value, Lockable &mutex) : BaseType(mutex), mValue(value) {}
    ConstUniqueLockPtr(const T &value, Lockable &mutex, std::adopt_lock_t) noexcept
        : BaseType(mutex, std::adopt_lock), mValue(value)
    {}
    ConstUniqueLockPtr(const T &value, Lockable &mutex, std::defer_lock_t) noexcept
        : BaseType(mutex, std::defer_lock), mValue(value)
    {}
    ConstUniqueLockPtr(const T &value, Lockable &mutex, std::try_to_lock_t) noexcept
        : BaseType(mutex, std::try_to_lock), mValue(value)
    {}

    ConstUniqueLockPtr(ConstUniqueLockPtr &&other) noexcept
        : BaseType(std::move(static_cast<BaseType &&>(other))), mValue(other.mValue)
    {}

    ConstUniqueLockPtr(const ConstUniqueLockPtr &) = delete;
    ConstUniqueLockPtr &operator=(const ConstUniqueLockPtr &) = delete;

    ~ConstUniqueLockPtr() = default;

    const T *operator->() const
    {
        ASSERT(this->owns_lock());
        return &mValue;
    }
    const T &operator*() const
    {
        ASSERT(this->owns_lock());
        return mValue;
    }

  protected:
    T const &mValue;
};

template <typename T, typename Lockable = std::mutex>
class UniqueLockPtr : public ConstUniqueLockPtr<T, Lockable>
{
  private:
    using BaseType = ConstUniqueLockPtr<T, Lockable>;

  public:
    UniqueLockPtr(T &value, Lockable &mutex) : BaseType(value, mutex) {}
    UniqueLockPtr(T &value, Lockable &mutex, std::adopt_lock_t) noexcept
        : BaseType(value, mutex, std::adopt_lock)
    {}
    UniqueLockPtr(T &value, Lockable &mutex, std::defer_lock_t) noexcept
        : BaseType(value, mutex, std::defer_lock)
    {}
    UniqueLockPtr(T &value, Lockable &mutex, std::try_to_lock_t) noexcept
        : BaseType(value, mutex, std::try_to_lock)
    {}

    UniqueLockPtr(UniqueLockPtr &&other) noexcept
        : BaseType(std::move(static_cast<BaseType &&>(other)))
    {}

    UniqueLockPtr(const UniqueLockPtr &) = delete;
    UniqueLockPtr &operator=(const UniqueLockPtr &) = delete;

    ~UniqueLockPtr() = default;

    T *operator->()
    {
        ASSERT(this->owns_lock());
        return const_cast<T *>(&this->mValue);
    }
    T &operator*()
    {
        ASSERT(this->owns_lock());
        return const_cast<T &>(this->mValue);
    }
};

template <typename SV>
struct SynchronizedValueUniqueLockPtr
{
    using type = UniqueLockPtr<typename SV::value_type, typename SV::mutex_type>;
};

template <typename SV>
struct SynchronizedValueUniqueLockPtr<const SV>
{
    using type = ConstUniqueLockPtr<typename SV::value_type, typename SV::mutex_type>;
};

template <typename T, typename Lockable = std::mutex>
class SynchronizedValue
{
  public:
    using value_type = T;
    using mutex_type = Lockable;

    SynchronizedValue() noexcept(std::is_nothrow_default_constructible<T>::value) : mValue() {}

    SynchronizedValue(const T &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
        : mValue(other)
    {}

    SynchronizedValue(T &&other) noexcept(std::is_nothrow_move_constructible<T>::value)
        : mValue(std::move(other))
    {}

    template <typename... Args>
    SynchronizedValue(Args &&... args) noexcept(noexcept(T(std::forward<Args>(args)...)))
        : mValue(std::forward<Args>(args)...)
    {}

    SynchronizedValue(const SynchronizedValue &other)
    {
        std::lock_guard<Lockable> lock(other.mMutex);
        mValue = other.mValue;
    }

    SynchronizedValue(SynchronizedValue &&other)
    {
        std::lock_guard<Lockable> lock(other.mMutex);
        mValue = std::move(other.mValue);
    }

    SynchronizedValue &operator=(const SynchronizedValue &other)
    {
        if (&other != this)
        {
            std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
            std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
            std::lock(lock1, lock2);
            mValue = other.mValue;
        }
        return *this;
    }

    SynchronizedValue &operator=(SynchronizedValue &&other)
    {
        if (&other != this)
        {
            std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
            std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
            std::lock(lock1, lock2);
            mValue = std::move(other.mValue);
        }
        return *this;
    }

    SynchronizedValue &operator=(const T &value)
    {
        {
            std::lock_guard<Lockable> lock(mMutex);
            mValue = value;
        }
        return *this;
    }

    SynchronizedValue &operator=(T &&value)
    {
        {
            std::lock_guard<Lockable> lock(mMutex);
            mValue = std::move(value);
        }
        return *this;
    }

    T get() const
    {
        std::lock_guard<Lockable> lock(mMutex);
        return mValue;
    }

    explicit operator T() const { return get(); }

    void swap(SynchronizedValue &other)
    {
        if (this == &other)
        {
            return;
        }
        std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
        std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
        std::lock(lock1, lock2);
        std::swap(mValue, other.mValue);
    }

    void swap(T &other)
    {
        std::lock_guard<Lockable> lock(mMutex);
        std::swap(mValue, other);
    }

    StrictLockPtr<T, Lockable> operator->() { return StrictLockPtr<T, Lockable>(mValue, mMutex); }
    ConstStrictLockPtr<T, Lockable> operator->() const
    {
        return ConstStrictLockPtr<T, Lockable>(mValue, mMutex);
    }

    StrictLockPtr<T, Lockable> synchronize() { return StrictLockPtr<T, Lockable>(mValue, mMutex); }
    ConstStrictLockPtr<T, Lockable> synchronize() const
    {
        return ConstStrictLockPtr<T, Lockable>(mValue, mMutex);
    }

    UniqueLockPtr<T, Lockable> unique_synchronize()
    {
        return UniqueLockPtr<T, Lockable>(mValue, mMutex);
    }
    ConstUniqueLockPtr<T, Lockable> unique_synchronize() const
    {
        return ConstUniqueLockPtr<T, Lockable>(mValue, mMutex);
    }

    UniqueLockPtr<T, Lockable> defer_synchronize() noexcept
    {
        return UniqueLockPtr<T, Lockable>(mValue, mMutex, std::defer_lock);
    }
    ConstUniqueLockPtr<T, Lockable> defer_synchronize() const noexcept
    {
        return ConstUniqueLockPtr<T, Lockable>(mValue, mMutex, std::defer_lock);
    }

    UniqueLockPtr<T, Lockable> try_to_synchronize() noexcept
    {
        return UniqueLockPtr<T, Lockable>(mValue, mMutex, std::try_to_lock);
    }
    ConstUniqueLockPtr<T, Lockable> try_to_synchronize() const noexcept
    {
        return ConstUniqueLockPtr<T, Lockable>(mValue, mMutex, std::try_to_lock);
    }

    UniqueLockPtr<T, Lockable> adopt_synchronize() noexcept
    {
        return UniqueLockPtr<T, Lockable>(mValue, mMutex, std::adopt_lock);
    }
    ConstUniqueLockPtr<T, Lockable> adopt_synchronize() const noexcept
    {
        return ConstUniqueLockPtr<T, Lockable>(mValue, mMutex, std::adopt_lock);
    }

    class DerefValue
    {
      public:
        DerefValue(DerefValue &&other) : mLock(std::move(other.mLock)), mValue(other.mValue) {}

        DerefValue(const DerefValue &) = delete;
        DerefValue &operator=(const DerefValue &) = delete;

        operator T &() { return mValue; }

        DerefValue &operator=(const T &other)
        {
            mValue = other;
            return *this;
        }

      private:
        explicit DerefValue(SynchronizedValue &outer) : mLock(outer.mMutex), mValue(outer.mValue) {}

        std::unique_lock<Lockable> mLock;
        T &mValue;

        friend class SynchronizedValue;
    };

    class ConstDerefValue
    {
      public:
        ConstDerefValue(ConstDerefValue &&other)
            : mLock(std::move(other.mLock)), mValue(other.mValue)
        {}

        ConstDerefValue(const ConstDerefValue &) = delete;
        ConstDerefValue &operator=(const ConstDerefValue &) = delete;

        operator const T &() { return mValue; }

      private:
        explicit ConstDerefValue(const SynchronizedValue &outer)
            : mLock(outer.mMutex), mValue(outer.mValue)
        {}

        std::unique_lock<Lockable> mLock;
        const T &mValue;

        friend class SynchronizedValue;
    };

    DerefValue operator*() { return DerefValue(*this); }
    ConstDerefValue operator*() const { return ConstDerefValue(*this); }

    template <typename OStream>
    void save(OStream &os) const
    {
        std::lock_guard<Lockable> lock(mMutex);
        os << mValue;
    }

    template <typename IStream>
    void load(IStream &is)
    {
        std::lock_guard<Lockable> lock(mMutex);
        is >> mValue;
    }

    bool operator==(const SynchronizedValue &other) const
    {
        std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
        std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
        std::lock(lock1, lock2);
        return mValue == other.mValue;
    }

    bool operator!=(const SynchronizedValue &other) const
    {
        std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
        std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
        std::lock(lock1, lock2);
        return mValue != other.mValue;
    }

    bool operator<(const SynchronizedValue &other) const
    {
        std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
        std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
        std::lock(lock1, lock2);
        return mValue < other.mValue;
    }

    bool operator>(const SynchronizedValue &other) const
    {
        std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
        std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
        std::lock(lock1, lock2);
        return mValue > other.mValue;
    }

    bool operator<=(const SynchronizedValue &other) const
    {
        std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
        std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
        std::lock(lock1, lock2);
        return mValue <= other.mValue;
    }

    bool operator>=(const SynchronizedValue &other) const
    {
        std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
        std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
        std::lock(lock1, lock2);
        return mValue >= other.mValue;
    }

    bool operator==(const T &other) const
    {
        std::lock_guard<Lockable> lock(mMutex);
        return mValue == other;
    }

    bool operator!=(const T &other) const
    {
        std::lock_guard<Lockable> lock(mMutex);
        return mValue != other;
    }

    bool operator<(const T &other) const
    {
        std::lock_guard<Lockable> lock(mMutex);
        return mValue < other;
    }

    bool operator>(const T &other) const
    {
        std::lock_guard<Lockable> lock(mMutex);
        return mValue > other;
    }

    bool operator<=(const T &other) const
    {
        std::lock_guard<Lockable> lock(mMutex);
        return mValue <= other;
    }

    bool operator>=(const T &other) const
    {
        std::lock_guard<Lockable> lock(mMutex);
        return mValue >= other;
    }

  private:
    T mValue;
    mutable Lockable mMutex;
};

template <typename OStream, typename T, typename L>
inline OStream &operator<<(OStream &os, SynchronizedValue<T, L> const &sv)
{
    sv.save(os);
    return os;
}

template <typename IStream, typename T, typename L>
inline IStream &operator>>(IStream &is, SynchronizedValue<T, L> &sv)
{
    sv.load(is);
    return is;
}

template <typename T, typename L>
bool operator==(const T &lhs, const SynchronizedValue<T, L> &rhs)
{
    return rhs == lhs;
}

template <typename T, typename L>
bool operator!=(const T &lhs, const SynchronizedValue<T, L> &rhs)
{
    return rhs != lhs;
}

template <typename T, typename L>
bool operator<(const T &lhs, const SynchronizedValue<T, L> &rhs)
{
    return rhs < lhs;
}

template <typename T, typename L>
bool operator>(const T &lhs, const SynchronizedValue<T, L> &rhs)
{
    return rhs > lhs;
}

template <typename T, typename L>
bool operator<=(const T &lhs, const SynchronizedValue<T, L> &rhs)
{
    return rhs <= lhs;
}

template <typename T, typename L>
bool operator>=(const T &lhs, const SynchronizedValue<T, L> &rhs)
{
    return rhs >= lhs;
}

}  // namespace angle

#endif  // COMMON_SYNCHRONIZEDVALUE_H_
