/*
 *  Copyright 2020 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 <vector>

#include "api/task_queue/to_queued_task.h"
#include "api/test/time_controller.h"
#include "api/units/time_delta.h"
#include "rtc_base/event.h"
#include "rtc_base/location.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_annotations.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/time_controller/real_time_controller.h"
#include "test/time_controller/simulated_time_controller.h"

namespace webrtc {
namespace {

using ::testing::ElementsAreArray;
using ::testing::TestParamInfo;
using ::testing::TestWithParam;
using ::testing::Values;

enum class TimeMode { kRealTime, kSimulated };

std::unique_ptr<TimeController> CreateTimeController(TimeMode mode) {
  switch (mode) {
    case TimeMode::kRealTime:
      return std::make_unique<RealTimeController>();
    case TimeMode::kSimulated:
      // Using an offset of 100000 to get nice fixed width and readable
      // timestamps in typical test scenarios.
      constexpr Timestamp kSimulatedStartTime = Timestamp::Seconds(100000);
      return std::make_unique<GlobalSimulatedTimeController>(
          kSimulatedStartTime);
  }
}

std::string ParamsToString(const TestParamInfo<webrtc::TimeMode>& param) {
  switch (param.param) {
    case webrtc::TimeMode::kRealTime:
      return "RealTime";
    case webrtc::TimeMode::kSimulated:
      return "SimulatedTime";
    default:
      RTC_DCHECK_NOTREACHED() << "Time mode not supported";
  }
}

// Keeps order of executions. May be called from different threads.
class ExecutionOrderKeeper {
 public:
  void Executed(int execution_id) {
    MutexLock lock(&mutex_);
    order_.push_back(execution_id);
  }

  std::vector<int> order() const {
    MutexLock lock(&mutex_);
    return order_;
  }

 private:
  mutable Mutex mutex_;
  std::vector<int> order_ RTC_GUARDED_BY(mutex_);
};

// Tests conformance between real time and simulated time time controller.
class SimulatedRealTimeControllerConformanceTest
    : public TestWithParam<webrtc::TimeMode> {};

TEST_P(SimulatedRealTimeControllerConformanceTest, ThreadPostOrderTest) {
  std::unique_ptr<TimeController> time_controller =
      CreateTimeController(GetParam());
  std::unique_ptr<rtc::Thread> thread = time_controller->CreateThread("thread");

  // Tasks on thread have to be executed in order in which they were
  // posted.
  ExecutionOrderKeeper execution_order;
  thread->PostTask([&]() { execution_order.Executed(1); });
  thread->PostTask([&]() { execution_order.Executed(2); });
  time_controller->AdvanceTime(TimeDelta::Millis(100));
  EXPECT_THAT(execution_order.order(), ElementsAreArray({1, 2}));
  // Destroy `thread` before `execution_order` to be sure `execution_order`
  // is not accessed on the posted task after it is destroyed.
  thread = nullptr;
}

TEST_P(SimulatedRealTimeControllerConformanceTest, ThreadPostDelayedOrderTest) {
  std::unique_ptr<TimeController> time_controller =
      CreateTimeController(GetParam());
  std::unique_ptr<rtc::Thread> thread = time_controller->CreateThread("thread");

  ExecutionOrderKeeper execution_order;
  thread->PostDelayedTask(ToQueuedTask([&]() { execution_order.Executed(2); }),
                          /*milliseconds=*/500);
  thread->PostTask(ToQueuedTask([&]() { execution_order.Executed(1); }));
  time_controller->AdvanceTime(TimeDelta::Millis(600));
  EXPECT_THAT(execution_order.order(), ElementsAreArray({1, 2}));
  // Destroy `thread` before `execution_order` to be sure `execution_order`
  // is not accessed on the posted task after it is destroyed.
  thread = nullptr;
}

TEST_P(SimulatedRealTimeControllerConformanceTest, ThreadPostInvokeOrderTest) {
  std::unique_ptr<TimeController> time_controller =
      CreateTimeController(GetParam());
  std::unique_ptr<rtc::Thread> thread = time_controller->CreateThread("thread");

  // Tasks on thread have to be executed in order in which they were
  // posted/invoked.
  ExecutionOrderKeeper execution_order;
  thread->PostTask([&]() { execution_order.Executed(1); });
  thread->Invoke<void>(RTC_FROM_HERE, [&]() { execution_order.Executed(2); });
  time_controller->AdvanceTime(TimeDelta::Millis(100));
  EXPECT_THAT(execution_order.order(), ElementsAreArray({1, 2}));
  // Destroy `thread` before `execution_order` to be sure `execution_order`
  // is not accessed on the posted task after it is destroyed.
  thread = nullptr;
}

TEST_P(SimulatedRealTimeControllerConformanceTest,
       ThreadPostInvokeFromThreadOrderTest) {
  std::unique_ptr<TimeController> time_controller =
      CreateTimeController(GetParam());
  std::unique_ptr<rtc::Thread> thread = time_controller->CreateThread("thread");

  // If task is invoked from thread X on thread X it has to be executed
  // immediately.
  ExecutionOrderKeeper execution_order;
  thread->PostTask([&]() {
    thread->PostTask([&]() { execution_order.Executed(2); });
    thread->Invoke<void>(RTC_FROM_HERE, [&]() { execution_order.Executed(1); });
  });
  time_controller->AdvanceTime(TimeDelta::Millis(100));
  EXPECT_THAT(execution_order.order(), ElementsAreArray({1, 2}));
  // Destroy `thread` before `execution_order` to be sure `execution_order`
  // is not accessed on the posted task after it is destroyed.
  thread = nullptr;
}

TEST_P(SimulatedRealTimeControllerConformanceTest,
       TaskQueuePostEventWaitOrderTest) {
  std::unique_ptr<TimeController> time_controller =
      CreateTimeController(GetParam());
  auto task_queue = time_controller->GetTaskQueueFactory()->CreateTaskQueue(
      "task_queue", webrtc::TaskQueueFactory::Priority::NORMAL);

  // Tasks on thread have to be executed in order in which they were
  // posted/invoked.
  ExecutionOrderKeeper execution_order;
  rtc::Event event;
  task_queue->PostTask(ToQueuedTask([&]() { execution_order.Executed(1); }));
  task_queue->PostTask(ToQueuedTask([&]() {
    execution_order.Executed(2);
    event.Set();
  }));
  EXPECT_TRUE(event.Wait(/*give_up_after_ms=*/100,
                         /*warn_after_ms=*/10'000));
  time_controller->AdvanceTime(TimeDelta::Millis(100));
  EXPECT_THAT(execution_order.order(), ElementsAreArray({1, 2}));
  // Destroy `task_queue` before `execution_order` to be sure `execution_order`
  // is not accessed on the posted task after it is destroyed.
  task_queue = nullptr;
}

INSTANTIATE_TEST_SUITE_P(ConformanceTest,
                         SimulatedRealTimeControllerConformanceTest,
                         Values(TimeMode::kRealTime, TimeMode::kSimulated),
                         ParamsToString);

}  // namespace
}  // namespace webrtc
