// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <zircon/assert.h>
#include <zircon/compiler.h>

#include <lockdep/common.h>
#include <lockdep/lock_class.h>
#include <lockdep/lock_policy.h>
#include <lockdep/lock_traits.h>

#include <type_traits>
#include <utility>

namespace lockdep {

namespace internal {

// Utility to deduce the LockType given any subclass of Lock<LockType>.
template <typename LockType>
LockType DeduceLockType(Lock<LockType>*);

// Determines the LockType of any subclass of Lock<LockType> or
// Lock<GlobalReference<LockType, Reference>>.
template <typename T>
using GetLockType = RemoveGlobalReference<
    decltype(DeduceLockType(static_cast<T*>(nullptr)))>;

// Trait type that determines whether the given LockType is nestable.
template <typename T>
struct IsNestable {
    using LockType = RemoveGlobalReference<T>;
    static constexpr bool Value =
        (LockTraits<LockType>::Flags & LockFlagsNestable) != 0;
};

// Trait type that determines whether the given policy type has a nested type
// tag named Shared.
template <typename LockPolicy, typename Enabled = void>
struct IsSharedLockPolicy {
    static constexpr bool Value = false;
};
template <typename LockPolicy>
struct IsSharedLockPolicy<LockPolicy,
                          std::void_t<typename LockPolicy::Shared>> {
    static constexpr bool Value = true;
};

// Enable if the given T is nestable and uses same type as LockType.
template <typename T, typename LockType>
using EnableIfNestable = typename std::enable_if<
    std::is_same<GetLockType<T>, LockType>::value &&
    IsNestable<GetLockType<T>>::Value>::type;

// Enable if the given T is not nestable and uses same type as LockType.
template <typename T, typename LockType>
using EnableIfNotNestable = typename std::enable_if<
    std::is_same<GetLockType<T>, LockType>::value &&
    !IsNestable<GetLockType<T>>::Value>::type;

template <typename LockType, typename Option>
using EnableIfShared = typename std::enable_if<
    IsSharedLockPolicy<LockPolicy<LockType, Option>>::Value>::type;

template <typename LockType, typename Option>
using EnableIfNotShared = typename std::enable_if<
    !IsSharedLockPolicy<LockPolicy<LockType, Option>>::Value>::type;

} // namespace internal

// Type tag to select the (private) ordered Guard constructor.
enum OrderedLockTag { OrderedLock };

// Type tag to select the adopting Guard constructor.
enum AdoptLockTag { AdoptLock };

// Base RAII type that automatically manages the duration of a lock acquisition.
// TODO(eieio): Specializations handle exclusive and shared lock acquisitions.
// These are largely identical except for the static lock analysis annotations.
// See if there is away to factor out the common logic for better
// maintainability.
template <typename LockType, typename Option = void, typename Enable = void>
class Guard;

// Specialization of Guard that acquires the given lock in exclusive mode.
template <typename LockType, typename Option>
class __TA_SCOPED_CAPABILITY Guard<LockType, Option,
                                   internal::EnableIfNotShared<LockType, Option>> {
    static_assert(
        !std::is_same<LockPolicy<LockType, Option>, AmbiguousOption>::value,
        "The Option argument of Guard<LockType, Option> must always "
        "be specified when the policy for LockType is defined using "
        "the macro LOCK_DEP_POLICY_OPTION(). See the macro docs for "
        "details.");

public:
    Guard(Guard&&) = delete;
    Guard(const Guard&) = delete;
    Guard& operator=(Guard&&) = delete;
    Guard& operator=(const Guard&) = delete;

    // Acquires the given lock. This constructor participates in overload
    // resolution when the underlying lock type is not nestable.
    template <typename Lockable, typename... Args,
              typename = internal::EnableIfNotNestable<Lockable, LockType>>
    Guard(Lockable* lock, Args&&... state_args)
        __TA_ACQUIRE(lock) __TA_ACQUIRE(lock->capability())
        : validator_{lock->id()}, lock_{&lock->lock()},
          state_{std::forward<Args>(state_args)...} { ValidateAndAcquire(); }

    // Acquires the given lock. This constructor participates in overload
    // resolution when the underlying lock type is nestable.
    template <typename Lockable, typename... Args,
              typename = internal::EnableIfNestable<Lockable, LockType>>
    Guard(Lockable* lock, uintptr_t order, Args&&... state_args)
        __TA_ACQUIRE(lock) __TA_ACQUIRE(lock->capability())
        : Guard{OrderedLock, lock, order, std::forward<Args>(state_args)...} {}

    // Destructor that automatically releases the lock if not already released.
    ~Guard() __TA_RELEASE() {
        Release();
    }

    // Releases the lock early before this guard instance goes out of scope.
    template <typename... Args>
    void Release(Args&&... args) __TA_RELEASE() {
        if (lock_ != nullptr) {
            LockPolicy<LockType, Option>::Release(lock_, &state_,
                                                  std::forward<Args>(args)...);
            validator_.ValidateRelease();
            lock_ = nullptr;
        }
    }

    // Returns true if the guard has an actively acquired lock.
    explicit operator bool() const { return lock_ != nullptr; }
    // Returns true if this guard wraps |lock|.
    bool wraps_lock(const LockType& lock) const { return &lock == lock_; }

    // Releases this scoped capability without releasing the underlying lock or
    // un-tracking the lock in the validator. Returns an rvalue reference to the
    // lock state and validator state which may be adopted by another Guard.
    // This is useful in the rare situation where a lock must be released by a
    // function called in the current protected scope. This is primarily needed
    // to keep the Clang static lock validator happy; static analysis complains
    // when a scoped capability is passed by pointer/reference and released in
    // another scope.
    //
    // Example:
    //  Guard<fbl::Mutex> guard{&lock};
    //
    //  // Setup actions...
    //
    //  DoTaskAndReleaseLock(guard.take());
    //
    Guard&& take() __TA_RELEASE() {
        return std::move(*this);
    }

    // Adopts the lock state and validator state. This constructor uses a type
    // tag argument to avoid automatic move constructor semantics.
    //
    // Example:
    //  Guard<fbl::Mutex> guard{AdoptLock, std::move(rvalue_arugment)};
    //
    Guard(AdoptLockTag, Guard&& other) __TA_ACQUIRE(other.lock_)
        : validator_{std::move(other.validator_)}, lock_{other.lock_},
          state_{std::move(other.state_)} { other.lock_ = nullptr; }

    // Temporarily releases and un-tracks the guarded lock before executing the
    // given callable Op and then re-acquires and tracks the lock. This permits
    // the same Guard instance to protect a larger scope while performing an
    // operation unlocked. This is especially useful in guarded loops:
    //
    //  Guard<fbl::Mutex> guard{&lock_};
    //  for (auto* entry : objects_.next()) {
    //      if (Pred(entry)) {
    //          objects_.erase(entry);
    //          guard.CallUnlocked([entry]() {
    //              // Unlocked operation on entry ...
    //          });
    //      }
    //  }
    //
    template <typename Op, typename... ReleaseArgs>
    void CallUnlocked(Op&& op, ReleaseArgs&&... release_args)
        __TA_NO_THREAD_SAFETY_ANALYSIS {
        ZX_DEBUG_ASSERT(lock_ != nullptr);

        LockPolicy<LockType, Option>::Release(
            lock_, &state_, std::forward<ReleaseArgs>(release_args)...);
        validator_.ValidateRelease();

        std::forward<Op>(op)();

        ValidateAndAcquire();
    }

private:
    template <size_t, typename, typename>
    friend class GuardMultiple;

    // Validates and acquires the lock. If the lock is a try-lock that failed
    // the release bookkeeping is performed and the guard is left in the empty
    // state. This method factors out the common body of the main constructors;
    // thread safety analysis is disabled to silence the unnecessary warning
    // about the conditional path that would not be raised in the constructor
    // body.
    void ValidateAndAcquire() __TA_NO_THREAD_SAFETY_ANALYSIS {
        validator_.ValidateAcquire();
        if (!LockPolicy<LockType, Option>::Acquire(lock_, &state_)) {
            lock_ = nullptr;
            validator_.ValidateRelease();
        }
    }

    // Ordered lock constructor used by the nestable lock constructor above and
    // by GuardMultiple.
    template <typename Lockable, typename... Args>
    Guard(OrderedLockTag, Lockable* lock,
          uintptr_t order, Args&&... state_args)
        __TA_ACQUIRE(lock) __TA_ACQUIRE(lock->capability())
        : validator_{lock->id(), order}, lock_{&lock->lock()},
          state_{std::forward<Args>(state_args)...} { ValidateAndAcquire(); }

    // Validator type used when lock validation is enabled. Provides the
    // AcquiredLockEntry instance and bookkeeping calls required by
    // ThreadLockState.
    struct LockValidator {
        LockValidator(LockClassId id, uintptr_t order = 0)
            : lock_entry{id, order} {}

        void ValidateAcquire() {
            ThreadLockState::Get()->Acquire(&lock_entry);
        }
        void ValidateRelease() {
            ThreadLockState::Get()->Release(&lock_entry);
        }

        AcquiredLockEntry lock_entry;
    };

    // Validator type used when lock validation is disabled.
    struct DummyValidator {
        DummyValidator(LockClassId, uintptr_t = 0) {}
        void ValidateAcquire() {}
        void ValidateRelease() {}
    };

    // Alias of the configured validator.
    using Validator = IfLockValidationEnabled<LockValidator, DummyValidator>;

    // The validator to use when acquiring and releasing the lock.
    Validator validator_;

    // Pointer to the acquired lock.
    LockType* lock_;

    // State to store in the guard as specified by the lock policy. For example,
    // this may be used to save IRQ state for spinlocks.
    typename LockPolicy<LockType, Option>::State state_;
};

// Specialization of Guard that acquires the given lock in shared mode.
template <typename LockType, typename Option>
class __TA_SCOPED_CAPABILITY Guard<LockType, Option,
                                   internal::EnableIfShared<LockType, Option>> {
    static_assert(
        !std::is_same<LockPolicy<LockType, Option>, AmbiguousOption>::value,
        "The Option argument of Guard<LockType, Option> must always "
        "be specified when the policy for LockType is defined using "
        "the macro LOCK_DEP_POLICY_OPTION(). See the macro docs for "
        "details.");

public:
    Guard(Guard&&) = delete;
    Guard(const Guard&) = delete;
    Guard& operator=(Guard&&) = delete;
    Guard& operator=(const Guard&) = delete;

    // Acquires the given lock. This constructor participates in overload
    // resolution when the underlying lock type is not nestable.
    template <typename Lockable, typename... Args,
              typename = internal::EnableIfNotNestable<Lockable, LockType>>
    Guard(Lockable* lock, Args&&... state_args)
        __TA_ACQUIRE_SHARED(lock) __TA_ACQUIRE_SHARED(lock->capability())
        : validator_{lock->id()}, lock_{&lock->lock()},
          state_{std::forward<Args>(state_args)...} { ValidateAndAcquire(); }

    // Acquires the given lock. This constructor participates in overload
    // resolution when the underlying lock type is nestable.
    template <typename Lockable, typename... Args,
              typename = internal::EnableIfNestable<Lockable, LockType>>
    Guard(Lockable* lock, uintptr_t order, Args&&... state_args)
        __TA_ACQUIRE_SHARED(lock) __TA_ACQUIRE_SHARED(lock->capability())
        : Guard{OrderedLock, lock, order, std::forward<Args>(state_args)...} {}

    // Destructor that automatically releases the lock if not already released.
    ~Guard() __TA_RELEASE() {
        Release();
    }

    // Releases the lock early before this guard instance goes out of scope.
    template <typename... Args>
    void Release(Args&&... args) __TA_RELEASE() {
        if (lock_ != nullptr) {
            LockPolicy<LockType, Option>::Release(lock_, &state_,
                                                  std::forward<Args>(args)...);
            validator_.ValidateRelease();
            lock_ = nullptr;
        }
    }

    // Returns true if the guard has an actively acquired lock.
    explicit operator bool() const { return lock_ != nullptr; }

    // Releases this scoped capability without releasing the underlying lock or
    // un-tracking the lock in the validator. Returns an rvalue reference to the
    // lock state and validator state which may be adopted by another Guard.
    // This is useful in the rare situation where a lock must be released by a
    // function called in the current protected scope. This is primarily needed
    // to keep the Clang static lock validator happy; static analysis complains
    // when a scoped capability is passed by pointer/reference and released in
    // another scope.
    //
    // Example:
    //  Guard<fbl::Mutex> guard{&lock};
    //
    //  // Setup actions...
    //
    //  DoTaskAndReleaseLock(guard.take());
    //
    Guard&& take() __TA_RELEASE() {
        return std::move(*this);
    }

    // Adopts the lock state and validator state. This constructor uses a type
    // tag argument to avoid automatic move constructor semantics.
    //
    // Example:
    //  Guard<fbl::Mutex> guard{AdoptLock, std::move(rvalue_arugment)};
    //
    Guard(AdoptLockTag, Guard&& other) __TA_ACQUIRE_SHARED(other.lock_)
        : validator_{std::move(other.validator_)}, lock_{other.lock_},
          state_{std::move(other.state_)} { other.lock_ = nullptr; }

    // Temporarily releases and un-tracks the guarded lock before executing the
    // given callable Op and then re-acquires and tracks the lock. This permits
    // the same Guard instance to protect a larger scope while performing an
    // operation unlocked. This is especially useful in guarded loops:
    //
    //  Guard<fbl::Mutex> guard{&lock_};
    //  for (auto* entry : objects_.next()) {
    //      if (Pred(entry)) {
    //          objects_.erase(entry);
    //          guard.CallUnlocked([entry]() {
    //              // Unlocked operation on entry ...
    //          });
    //      }
    //  }
    //
    template <typename Op, typename... ReleaseArgs>
    void CallUnlocked(Op&& op, ReleaseArgs&&... release_args)
        __TA_NO_THREAD_SAFETY_ANALYSIS {
        ZX_DEBUG_ASSERT(lock_ != nullptr);

        LockPolicy<LockType, Option>::Release(
            lock_, &state_, std::forward<ReleaseArgs>(release_args)...);
        validator_.ValidateRelease();

        std::forward<Op>(op)();

        ValidateAndAcquire();
    }

private:
    template <size_t, typename, typename>
    friend class GuardMultiple;

    // Validates and acquires the lock. If the lock is a try-lock that failed
    // the release bookkeeping is performed and the guard is left in the empty
    // state. This method factors out the common body of the main constructors;
    // thread safety analysis is disabled to silence the unnecessary warning
    // about the conditional path that would not be raised in the constructor
    // body.
    void ValidateAndAcquire() __TA_NO_THREAD_SAFETY_ANALYSIS {
        validator_.ValidateAcquire();
        if (!LockPolicy<LockType, Option>::Acquire(lock_, &state_)) {
            lock_ = nullptr;
            validator_.ValidateRelease();
        }
    }

    // Ordered lock constructor used by the nestable lock constructor above and
    // by GuardMultiple.
    template <typename Lockable, typename... Args>
    Guard(OrderedLockTag, Lockable* lock,
          uintptr_t order, Args&&... state_args)
        __TA_ACQUIRE_SHARED(lock) __TA_ACQUIRE_SHARED(lock->capability())
        : validator_{lock->id(), order}, lock_{&lock->lock()},
          state_{std::forward<Args>(state_args)...} { ValidateAndAcquire(); }

    // Validator type used when lock validation is enabled. Provides the
    // AcquiredLockEntry instance and bookkeeping calls required by
    // ThreadLockState.
    struct LockValidator {
        LockValidator(LockClassId id, uintptr_t order = 0)
            : lock_entry{id, order} {}

        void ValidateAcquire() {
            ThreadLockState::Get()->Acquire(&lock_entry);
        }
        void ValidateRelease() {
            ThreadLockState::Get()->Release(&lock_entry);
        }

        AcquiredLockEntry lock_entry;
    };

    // Validator type used when lock validation is disabled.
    struct DummyValidator {
        DummyValidator(LockClassId, uintptr_t = 0) {}
        void ValidateAcquire() {}
        void ValidateRelease() {}
    };

    // Alias of the configured validator.
    using Validator = IfLockValidationEnabled<LockValidator, DummyValidator>;

    // The validator to use when acquiring and releasing the lock.
    Validator validator_;

    // Pointer to the acquired lock.
    LockType* lock_;

    // State to store in the guard as specified by the lock policy. For example,
    // this may be used to save IRQ state for spinlocks.
    typename LockPolicy<LockType, Option>::State state_;
};

} // namespace lockdep
