/*
 *  Copyright (c) 2012 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 <utility>

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/task_queue.h"
#include "webrtc/base/timeutils.h"
#include "webrtc/modules/include/module.h"
#include "webrtc/modules/utility/source/process_thread_impl.h"

namespace webrtc {

using ::testing::_;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SetArgPointee;

// The length of time, in milliseconds, to wait for an event to become signaled.
// Set to a fairly large value as there is quite a bit of variation on some
// Windows bots.
static const int kEventWaitTimeout = 500;

class MockModule : public Module {
 public:
  MOCK_METHOD0(TimeUntilNextProcess, int64_t());
  MOCK_METHOD0(Process, void());
  MOCK_METHOD1(ProcessThreadAttached, void(ProcessThread*));
};

class RaiseEventTask : public rtc::QueuedTask {
 public:
  RaiseEventTask(EventWrapper* event) : event_(event) {}
  bool Run() override {
    event_->Set();
    return true;
  }

 private:
  EventWrapper* event_;
};

ACTION_P(SetEvent, event) {
  event->Set();
}

ACTION_P(Increment, counter) {
  ++(*counter);
}

ACTION_P(SetTimestamp, ptr) {
  *ptr = rtc::TimeMillis();
}

TEST(ProcessThreadImpl, StartStop) {
  ProcessThreadImpl thread("ProcessThread");
  thread.Start();
  thread.Stop();
}

TEST(ProcessThreadImpl, MultipleStartStop) {
  ProcessThreadImpl thread("ProcessThread");
  for (int i = 0; i < 5; ++i) {
    thread.Start();
    thread.Stop();
  }
}

// Verifies that we get at least call back to Process() on the worker thread.
TEST(ProcessThreadImpl, ProcessCall) {
  ProcessThreadImpl thread("ProcessThread");
  thread.Start();

  std::unique_ptr<EventWrapper> event(EventWrapper::Create());

  MockModule module;
  EXPECT_CALL(module, TimeUntilNextProcess()).WillRepeatedly(Return(0));
  EXPECT_CALL(module, Process())
      .WillOnce(DoAll(SetEvent(event.get()), Return()))
      .WillRepeatedly(Return());
  EXPECT_CALL(module, ProcessThreadAttached(&thread)).Times(1);

  thread.RegisterModule(&module);
  EXPECT_EQ(kEventSignaled, event->Wait(kEventWaitTimeout));

  EXPECT_CALL(module, ProcessThreadAttached(nullptr)).Times(1);
  thread.Stop();
}

// Same as ProcessCall except the module is registered before the
// call to Start().
TEST(ProcessThreadImpl, ProcessCall2) {
  ProcessThreadImpl thread("ProcessThread");
  std::unique_ptr<EventWrapper> event(EventWrapper::Create());

  MockModule module;
  EXPECT_CALL(module, TimeUntilNextProcess()).WillRepeatedly(Return(0));
  EXPECT_CALL(module, Process())
      .WillOnce(DoAll(SetEvent(event.get()), Return()))
      .WillRepeatedly(Return());

  thread.RegisterModule(&module);

  EXPECT_CALL(module, ProcessThreadAttached(&thread)).Times(1);
  thread.Start();
  EXPECT_EQ(kEventSignaled, event->Wait(kEventWaitTimeout));

  EXPECT_CALL(module, ProcessThreadAttached(nullptr)).Times(1);
  thread.Stop();
}

// Tests setting up a module for callbacks and then unregister that module.
// After unregistration, we should not receive any further callbacks.
TEST(ProcessThreadImpl, Deregister) {
  ProcessThreadImpl thread("ProcessThread");
  std::unique_ptr<EventWrapper> event(EventWrapper::Create());

  int process_count = 0;
  MockModule module;
  EXPECT_CALL(module, TimeUntilNextProcess()).WillRepeatedly(Return(0));
  EXPECT_CALL(module, Process())
      .WillOnce(DoAll(SetEvent(event.get()),
                      Increment(&process_count),
                      Return()))
      .WillRepeatedly(DoAll(Increment(&process_count), Return()));

  thread.RegisterModule(&module);

  EXPECT_CALL(module, ProcessThreadAttached(&thread)).Times(1);
  thread.Start();

  EXPECT_EQ(kEventSignaled, event->Wait(kEventWaitTimeout));

  EXPECT_CALL(module, ProcessThreadAttached(nullptr)).Times(1);
  thread.DeRegisterModule(&module);

  EXPECT_GE(process_count, 1);
  int count_after_deregister = process_count;

  // We shouldn't get any more callbacks.
  EXPECT_EQ(kEventTimeout, event->Wait(20));
  EXPECT_EQ(count_after_deregister, process_count);
  thread.Stop();
}

// Helper function for testing receiving a callback after a certain amount of
// time.  There's some variance of timing built into it to reduce chance of
// flakiness on bots.
void ProcessCallAfterAFewMs(int64_t milliseconds) {
  ProcessThreadImpl thread("ProcessThread");
  thread.Start();

  std::unique_ptr<EventWrapper> event(EventWrapper::Create());

  MockModule module;
  int64_t start_time = 0;
  int64_t called_time = 0;
  EXPECT_CALL(module, TimeUntilNextProcess())
      .WillOnce(DoAll(SetTimestamp(&start_time),
                      Return(milliseconds)))
      .WillRepeatedly(Return(milliseconds));
  EXPECT_CALL(module, Process())
      .WillOnce(DoAll(SetTimestamp(&called_time),
                      SetEvent(event.get()),
                      Return()))
      .WillRepeatedly(Return());

  EXPECT_CALL(module, ProcessThreadAttached(&thread)).Times(1);
  thread.RegisterModule(&module);

  // Add a buffer of 50ms due to slowness of some trybots
  // (e.g. win_drmemory_light)
  EXPECT_EQ(kEventSignaled, event->Wait(milliseconds + 50));

  EXPECT_CALL(module, ProcessThreadAttached(nullptr)).Times(1);
  thread.Stop();

  ASSERT_GT(start_time, 0);
  ASSERT_GT(called_time, 0);
  // Use >= instead of > since due to rounding and timer accuracy (or lack
  // thereof), can make the test run in "0"ms time.
  EXPECT_GE(called_time, start_time);
  // Check for an acceptable range.
  uint32_t diff = called_time - start_time;
  EXPECT_GE(diff, milliseconds - 15);
  EXPECT_LT(diff, milliseconds + 15);
}

// DISABLED for now since the virtual build bots are too slow :(
// TODO(tommi): Fix.
TEST(ProcessThreadImpl, DISABLED_ProcessCallAfter5ms) {
  ProcessCallAfterAFewMs(5);
}

// DISABLED for now since the virtual build bots are too slow :(
// TODO(tommi): Fix.
TEST(ProcessThreadImpl, DISABLED_ProcessCallAfter50ms) {
  ProcessCallAfterAFewMs(50);
}

// DISABLED for now since the virtual build bots are too slow :(
// TODO(tommi): Fix.
TEST(ProcessThreadImpl, DISABLED_ProcessCallAfter200ms) {
  ProcessCallAfterAFewMs(200);
}

// Runs callbacks with the goal of getting up to 50 callbacks within a second
// (on average 1 callback every 20ms).  On real hardware, we're usually pretty
// close to that, but the test bots that run on virtual machines, will
// typically be in the range 30-40 callbacks.
// DISABLED for now since this can take up to 2 seconds to run on the slowest
// build bots.
// TODO(tommi): Fix.
TEST(ProcessThreadImpl, DISABLED_Process50Times) {
  ProcessThreadImpl thread("ProcessThread");
  thread.Start();

  std::unique_ptr<EventWrapper> event(EventWrapper::Create());

  MockModule module;
  int callback_count = 0;
  // Ask for a callback after 20ms.
  EXPECT_CALL(module, TimeUntilNextProcess())
      .WillRepeatedly(Return(20));
  EXPECT_CALL(module, Process())
      .WillRepeatedly(DoAll(Increment(&callback_count),
                            Return()));

  EXPECT_CALL(module, ProcessThreadAttached(&thread)).Times(1);
  thread.RegisterModule(&module);

  EXPECT_EQ(kEventTimeout, event->Wait(1000));

  EXPECT_CALL(module, ProcessThreadAttached(nullptr)).Times(1);
  thread.Stop();

  printf("Callback count: %i\n", callback_count);
  // Check that we got called back up to 50 times.
  // Some of the try bots run on slow virtual machines, so the lower bound
  // is much more relaxed to avoid flakiness.
  EXPECT_GE(callback_count, 25);
  EXPECT_LE(callback_count, 50);
}

// Tests that we can wake up the worker thread to give us a callback right
// away when we know the thread is sleeping.
TEST(ProcessThreadImpl, WakeUp) {
  ProcessThreadImpl thread("ProcessThread");
  thread.Start();

  std::unique_ptr<EventWrapper> started(EventWrapper::Create());
  std::unique_ptr<EventWrapper> called(EventWrapper::Create());

  MockModule module;
  int64_t start_time;
  int64_t called_time;

  // Ask for a callback after 1000ms.
  // TimeUntilNextProcess will be called twice.
  // The first time we use it to get the thread into a waiting state.
  // Then we  wake the thread and there should not be another call made to
  // TimeUntilNextProcess before Process() is called.
  // The second time TimeUntilNextProcess is then called, is after Process
  // has been called and we don't expect any more calls.
  EXPECT_CALL(module, TimeUntilNextProcess())
      .WillOnce(DoAll(SetTimestamp(&start_time),
                      SetEvent(started.get()),
                      Return(1000)))
      .WillOnce(Return(1000));
  EXPECT_CALL(module, Process())
      .WillOnce(
          DoAll(SetTimestamp(&called_time), SetEvent(called.get()), Return()))
      .WillRepeatedly(Return());

  EXPECT_CALL(module, ProcessThreadAttached(&thread)).Times(1);
  thread.RegisterModule(&module);

  EXPECT_EQ(kEventSignaled, started->Wait(kEventWaitTimeout));
  thread.WakeUp(&module);
  EXPECT_EQ(kEventSignaled, called->Wait(kEventWaitTimeout));

  EXPECT_CALL(module, ProcessThreadAttached(nullptr)).Times(1);
  thread.Stop();

  EXPECT_GE(called_time, start_time);
  uint32_t diff = called_time - start_time;
  // We should have been called back much quicker than 1sec.
  EXPECT_LE(diff, 100u);
}

// Tests that we can post a task that gets run straight away on the worker
// thread.
TEST(ProcessThreadImpl, PostTask) {
  ProcessThreadImpl thread("ProcessThread");
  std::unique_ptr<EventWrapper> task_ran(EventWrapper::Create());
  std::unique_ptr<RaiseEventTask> task(new RaiseEventTask(task_ran.get()));
  thread.Start();
  thread.PostTask(std::move(task));
  EXPECT_EQ(kEventSignaled, task_ran->Wait(kEventWaitTimeout));
  thread.Stop();
}

}  // namespace webrtc
