/*
 *  Copyright 2014 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 <set>
#include <vector>

#include "webrtc/base/criticalsection.h"
#include "webrtc/base/event.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/scopedptrcollection.h"
#include "webrtc/base/thread.h"

namespace rtc {

namespace {

const int kLongTime = 10000;  // 10 seconds
const int kNumThreads = 16;
const int kOperationsToRun = 1000;

template <class T>
class AtomicOpRunner : public MessageHandler {
 public:
  explicit AtomicOpRunner(int initial_value)
      : value_(initial_value),
        threads_active_(0),
        start_event_(true, false),
        done_event_(true, false) {}

  int value() const { return value_; }

  bool Run() {
    // Signal all threads to start.
    start_event_.Set();

    // Wait for all threads to finish.
    return done_event_.Wait(kLongTime);
  }

  void SetExpectedThreadCount(int count) {
    threads_active_ = count;
  }

  virtual void OnMessage(Message* msg) {
    std::vector<int> values;
    values.reserve(kOperationsToRun);

    // Wait to start.
    ASSERT_TRUE(start_event_.Wait(kLongTime));

    // Generate a bunch of values by updating value_ atomically.
    for (int i = 0; i < kOperationsToRun; ++i) {
      values.push_back(T::AtomicOp(&value_));
    }

    { // Add them all to the set.
      CritScope cs(&all_values_crit_);
      for (size_t i = 0; i < values.size(); ++i) {
        std::pair<std::set<int>::iterator, bool> result =
            all_values_.insert(values[i]);
        // Each value should only be taken by one thread, so if this value
        // has already been added, something went wrong.
        EXPECT_TRUE(result.second)
            << "Thread=" << Thread::Current() << " value=" << values[i];
      }
    }

    // Signal that we're done.
    if (AtomicOps::Decrement(&threads_active_) == 0) {
      done_event_.Set();
    }
  }

 private:
  int value_;
  int threads_active_;
  CriticalSection all_values_crit_;
  std::set<int> all_values_;
  Event start_event_;
  Event done_event_;
};

struct IncrementOp {
  static int AtomicOp(int* i) { return AtomicOps::Increment(i); }
};

struct DecrementOp {
  static int AtomicOp(int* i) { return AtomicOps::Decrement(i); }
};

void StartThreads(ScopedPtrCollection<Thread>* threads,
                  MessageHandler* handler) {
  for (int i = 0; i < kNumThreads; ++i) {
    Thread* thread = new Thread();
    thread->Start();
    thread->Post(handler);
    threads->PushBack(thread);
  }
}

}  // namespace

TEST(AtomicOpsTest, Simple) {
  int value = 0;
  EXPECT_EQ(1, AtomicOps::Increment(&value));
  EXPECT_EQ(1, value);
  EXPECT_EQ(2, AtomicOps::Increment(&value));
  EXPECT_EQ(2, value);
  EXPECT_EQ(1, AtomicOps::Decrement(&value));
  EXPECT_EQ(1, value);
  EXPECT_EQ(0, AtomicOps::Decrement(&value));
  EXPECT_EQ(0, value);
}

TEST(AtomicOpsTest, Increment) {
  // Create and start lots of threads.
  AtomicOpRunner<IncrementOp> runner(0);
  ScopedPtrCollection<Thread> threads;
  StartThreads(&threads, &runner);
  runner.SetExpectedThreadCount(kNumThreads);

  // Release the hounds!
  EXPECT_TRUE(runner.Run());
  EXPECT_EQ(kOperationsToRun * kNumThreads, runner.value());
}

TEST(AtomicOpsTest, Decrement) {
  // Create and start lots of threads.
  AtomicOpRunner<DecrementOp> runner(kOperationsToRun * kNumThreads);
  ScopedPtrCollection<Thread> threads;
  StartThreads(&threads, &runner);
  runner.SetExpectedThreadCount(kNumThreads);

  // Release the hounds!
  EXPECT_TRUE(runner.Run());
  EXPECT_EQ(0, runner.value());
}

}  // namespace rtc
