/*
 *  Copyright (c) 2016 The WebRTC 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 in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/thread_annotations.h"
#include "test/gtest.h"

namespace {

class RTC_LOCKABLE Lock {
 public:
  void EnterWrite() const RTC_EXCLUSIVE_LOCK_FUNCTION() {}
  void EnterRead() const RTC_SHARED_LOCK_FUNCTION() {}
  bool TryEnterWrite() const RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
    return true;
  }
  bool TryEnterRead() const RTC_SHARED_TRYLOCK_FUNCTION(true) { return true; }
  void Leave() const RTC_UNLOCK_FUNCTION() {}
};

class RTC_SCOPED_LOCKABLE ScopeLock {
 public:
  explicit ScopeLock(const Lock& lock) RTC_EXCLUSIVE_LOCK_FUNCTION(lock) {}
  ~ScopeLock() RTC_UNLOCK_FUNCTION() {}
};

class ThreadSafe {
 public:
  ThreadSafe() {
    pt_protected_by_lock_ = new int;
    pt_protected_by_anything_ = new int;
  }

  ~ThreadSafe() {
    delete pt_protected_by_lock_;
    delete pt_protected_by_anything_;
  }

  void LockInOrder() {
    anylock_.EnterWrite();
    lock_.EnterWrite();
    pt_lock_.EnterWrite();

    pt_lock_.Leave();
    lock_.Leave();
    anylock_.Leave();
  }

  void UnprotectedFunction() RTC_LOCKS_EXCLUDED(anylock_, lock_, pt_lock_) {
    // Can access unprotected Value.
    unprotected_ = 15;
    // Can access pointers themself, but not data they point to.
    int* tmp = pt_protected_by_lock_;
    pt_protected_by_lock_ = pt_protected_by_anything_;
    pt_protected_by_anything_ = tmp;
  }

  void ReadProtected() {
    lock_.EnterRead();
    unprotected_ = protected_by_anything_;
    unprotected_ = protected_by_lock_;
    lock_.Leave();

    if (pt_lock_.TryEnterRead()) {
      unprotected_ = *pt_protected_by_anything_;
      unprotected_ = *pt_protected_by_lock_;
      pt_lock_.Leave();
    }

    anylock_.EnterRead();
    unprotected_ = protected_by_anything_;
    unprotected_ = *pt_protected_by_anything_;
    anylock_.Leave();
  }

  void WriteProtected() {
    lock_.EnterWrite();
    protected_by_anything_ = unprotected_;
    protected_by_lock_ = unprotected_;
    lock_.Leave();

    if (pt_lock_.TryEnterWrite()) {
      *pt_protected_by_anything_ = unprotected_;
      *pt_protected_by_lock_ = unprotected_;
      pt_lock_.Leave();
    }

    anylock_.EnterWrite();
    protected_by_anything_ = unprotected_;
    *pt_protected_by_anything_ = unprotected_;
    anylock_.Leave();
  }

  void CallReadProtectedFunction() {
    lock_.EnterRead();
    pt_lock_.EnterRead();
    ReadProtectedFunction();
    pt_lock_.Leave();
    lock_.Leave();
  }

  void CallWriteProtectedFunction() {
    ScopeLock scope_lock(GetLock());
    ScopeLock pt_scope_lock(pt_lock_);
    WriteProtectedFunction();
  }

 private:
  void ReadProtectedFunction() RTC_SHARED_LOCKS_REQUIRED(lock_, pt_lock_) {
    unprotected_ = protected_by_lock_;
    unprotected_ = *pt_protected_by_lock_;
  }

  void WriteProtectedFunction() RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_, pt_lock_) {
    int x = protected_by_lock_;
    *pt_protected_by_lock_ = x;
    protected_by_lock_ = unprotected_;
  }

  const Lock& GetLock() RTC_LOCK_RETURNED(lock_) { return lock_; }

  Lock anylock_ RTC_ACQUIRED_BEFORE(lock_);
  Lock lock_;
  Lock pt_lock_ RTC_ACQUIRED_AFTER(lock_);

  int unprotected_ = 0;

  int protected_by_lock_ RTC_GUARDED_BY(lock_) = 0;
  int protected_by_anything_ RTC_GUARDED_VAR = 0;

  int* pt_protected_by_lock_ RTC_PT_GUARDED_BY(pt_lock_);
  int* pt_protected_by_anything_ RTC_PT_GUARDED_VAR;
};

}  // namespace

TEST(ThreadAnnotationsTest, Test) {
  // This test ensure thread annotations doesn't break compilation.
  // Thus no run-time expectations.
  ThreadSafe t;
  t.LockInOrder();
  t.UnprotectedFunction();
  t.ReadProtected();
  t.WriteProtected();
  t.CallReadProtectedFunction();
  t.CallWriteProtectedFunction();
}
