/*
 *  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 "webrtc/modules/include/module.h"
#include "webrtc/modules/utility/source/process_thread_impl.h"
#include "webrtc/rtc_base/location.h"
#include "webrtc/rtc_base/task_queue.h"
#include "webrtc/rtc_base/timeutils.h"
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.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())
      .WillOnce(Return(0))
      .WillRepeatedly(Return(1));
  EXPECT_CALL(module, Process())
      .WillOnce(DoAll(SetEvent(event.get()), Return()))
      .WillRepeatedly(Return());
  EXPECT_CALL(module, ProcessThreadAttached(&thread)).Times(1);

  thread.RegisterModule(&module, RTC_FROM_HERE);
  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())
      .WillOnce(Return(0))
      .WillRepeatedly(Return(1));
  EXPECT_CALL(module, Process())
      .WillOnce(DoAll(SetEvent(event.get()), Return()))
      .WillRepeatedly(Return());

  thread.RegisterModule(&module, RTC_FROM_HERE);

  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())
      .WillOnce(Return(0))
      .WillRepeatedly(Return(1));
  EXPECT_CALL(module, Process())
      .WillOnce(DoAll(SetEvent(event.get()),
                      Increment(&process_count),
                      Return()))
      .WillRepeatedly(DoAll(Increment(&process_count), Return()));

  thread.RegisterModule(&module, RTC_FROM_HERE);

  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, RTC_FROM_HERE);

  // 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, RTC_FROM_HERE);

  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, RTC_FROM_HERE);

  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
