/*
 *  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 "webrtc/rtc_base/thread_annotations.h"
#include "webrtc/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() 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() SHARED_LOCKS_REQUIRED(lock_, pt_lock_) {
    unprotected_ = protected_by_lock_;
    unprotected_ = *pt_protected_by_lock_;
  }

  void WriteProtectedFunction() 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_ ACQUIRED_BEFORE(lock_);
  Lock lock_;
  Lock pt_lock_ ACQUIRED_AFTER(lock_);

  int unprotected_ = 0;

  int protected_by_lock_ 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();
}
