/*
 *  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() 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();
}
