/*
 *  Copyright 2011 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 <memory>

#include "webrtc/base/common.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/messagehandler.h"
#include "webrtc/base/messagequeue.h"
#include "webrtc/base/sharedexclusivelock.h"
#include "webrtc/base/thread.h"
#include "webrtc/base/timeutils.h"

#if defined(MEMORY_SANITIZER)
// Flaky under MemorySanitizer, see
// https://bugs.chromium.org/p/webrtc/issues/detail?id=5824
#define MAYBE_TestSharedExclusive DISABLED_TestSharedExclusive
#define MAYBE_TestExclusiveExclusive DISABLED_TestExclusiveExclusive
#else
#define MAYBE_TestSharedExclusive TestSharedExclusive
#define MAYBE_TestExclusiveExclusive TestExclusiveExclusive
#endif

namespace rtc {

static const uint32_t kMsgRead = 0;
static const uint32_t kMsgWrite = 0;
static const int kNoWaitThresholdInMs = 10;
static const int kWaitThresholdInMs = 80;
static const int kProcessTimeInMs = 100;
static const int kProcessTimeoutInMs = 5000;

class SharedExclusiveTask : public MessageHandler {
 public:
  SharedExclusiveTask(SharedExclusiveLock* shared_exclusive_lock,
                      int* value,
                      bool* done)
      : shared_exclusive_lock_(shared_exclusive_lock),
        waiting_time_in_ms_(0),
        value_(value),
        done_(done) {
    worker_thread_.reset(new Thread());
    worker_thread_->Start();
  }

  int64_t waiting_time_in_ms() const { return waiting_time_in_ms_; }

 protected:
  std::unique_ptr<Thread> worker_thread_;
  SharedExclusiveLock* shared_exclusive_lock_;
  int64_t waiting_time_in_ms_;
  int* value_;
  bool* done_;
};

class ReadTask : public SharedExclusiveTask {
 public:
  ReadTask(SharedExclusiveLock* shared_exclusive_lock, int* value, bool* done)
      : SharedExclusiveTask(shared_exclusive_lock, value, done) {
  }

  void PostRead(int* value) {
    worker_thread_->Post(this, kMsgRead, new TypedMessageData<int*>(value));
  }

 private:
  virtual void OnMessage(Message* message) {
    ASSERT(rtc::Thread::Current() == worker_thread_.get());
    ASSERT(message != NULL);
    ASSERT(message->message_id == kMsgRead);

    TypedMessageData<int*>* message_data =
        static_cast<TypedMessageData<int*>*>(message->pdata);

    int64_t start_time = TimeMillis();
    {
      SharedScope ss(shared_exclusive_lock_);
      waiting_time_in_ms_ = TimeDiff(TimeMillis(), start_time);

      Thread::SleepMs(kProcessTimeInMs);
      *message_data->data() = *value_;
      *done_ = true;
    }
    delete message->pdata;
    message->pdata = NULL;
  }
};

class WriteTask : public SharedExclusiveTask {
 public:
  WriteTask(SharedExclusiveLock* shared_exclusive_lock, int* value, bool* done)
      : SharedExclusiveTask(shared_exclusive_lock, value, done) {
  }

  void PostWrite(int value) {
    worker_thread_->Post(this, kMsgWrite, new TypedMessageData<int>(value));
  }

 private:
  virtual void OnMessage(Message* message) {
    ASSERT(rtc::Thread::Current() == worker_thread_.get());
    ASSERT(message != NULL);
    ASSERT(message->message_id == kMsgWrite);

    TypedMessageData<int>* message_data =
        static_cast<TypedMessageData<int>*>(message->pdata);

    int64_t start_time = TimeMillis();
    {
      ExclusiveScope es(shared_exclusive_lock_);
      waiting_time_in_ms_ = TimeDiff(TimeMillis(), start_time);

      Thread::SleepMs(kProcessTimeInMs);
      *value_ = message_data->data();
      *done_ = true;
    }
    delete message->pdata;
    message->pdata = NULL;
  }
};

// Unit test for SharedExclusiveLock.
class SharedExclusiveLockTest
    : public testing::Test {
 public:
  SharedExclusiveLockTest() : value_(0) {
  }

  virtual void SetUp() {
    shared_exclusive_lock_.reset(new SharedExclusiveLock());
  }

 protected:
  std::unique_ptr<SharedExclusiveLock> shared_exclusive_lock_;
  int value_;
};

// Flaky: https://code.google.com/p/webrtc/issues/detail?id=3318
TEST_F(SharedExclusiveLockTest, TestSharedShared) {
  int value0, value1;
  bool done0, done1;
  ReadTask reader0(shared_exclusive_lock_.get(), &value_, &done0);
  ReadTask reader1(shared_exclusive_lock_.get(), &value_, &done1);

  // Test shared locks can be shared without waiting.
  {
    SharedScope ss(shared_exclusive_lock_.get());
    value_ = 1;
    done0 = false;
    done1 = false;
    reader0.PostRead(&value0);
    reader1.PostRead(&value1);
    Thread::SleepMs(kProcessTimeInMs);
  }

  EXPECT_TRUE_WAIT(done0, kProcessTimeoutInMs);
  EXPECT_EQ(1, value0);
  EXPECT_LE(reader0.waiting_time_in_ms(), kNoWaitThresholdInMs);
  EXPECT_TRUE_WAIT(done1, kProcessTimeoutInMs);
  EXPECT_EQ(1, value1);
  EXPECT_LE(reader1.waiting_time_in_ms(), kNoWaitThresholdInMs);
}

TEST_F(SharedExclusiveLockTest, MAYBE_TestSharedExclusive) {
  bool done;
  WriteTask writer(shared_exclusive_lock_.get(), &value_, &done);

  // Test exclusive lock needs to wait for shared lock.
  {
    SharedScope ss(shared_exclusive_lock_.get());
    value_ = 1;
    done = false;
    writer.PostWrite(2);
    Thread::SleepMs(kProcessTimeInMs);
    EXPECT_EQ(1, value_);
  }

  EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs);
  EXPECT_EQ(2, value_);
  EXPECT_GE(writer.waiting_time_in_ms(), kWaitThresholdInMs);
}

TEST_F(SharedExclusiveLockTest, TestExclusiveShared) {
  int value;
  bool done;
  ReadTask reader(shared_exclusive_lock_.get(), &value_, &done);

  // Test shared lock needs to wait for exclusive lock.
  {
    ExclusiveScope es(shared_exclusive_lock_.get());
    value_ = 1;
    done = false;
    reader.PostRead(&value);
    Thread::SleepMs(kProcessTimeInMs);
    value_ = 2;
  }

  EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs);
  EXPECT_EQ(2, value);
  EXPECT_GE(reader.waiting_time_in_ms(), kWaitThresholdInMs);
}

TEST_F(SharedExclusiveLockTest, MAYBE_TestExclusiveExclusive) {
  bool done;
  WriteTask writer(shared_exclusive_lock_.get(), &value_, &done);

  // Test exclusive lock needs to wait for exclusive lock.
  {
    ExclusiveScope es(shared_exclusive_lock_.get());
    value_ = 1;
    done = false;
    writer.PostWrite(2);
    Thread::SleepMs(kProcessTimeInMs);
    EXPECT_EQ(1, value_);
  }

  EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs);
  EXPECT_EQ(2, value_);
  EXPECT_GE(writer.waiting_time_in_ms(), kWaitThresholdInMs);
}

}  // namespace rtc
