/*
 *  Copyright 2019 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 "test/time_controller/simulated_time_controller.h"

#include <algorithm>
#include <memory>
#include <string>
#include <utility>

#include "api/task_queue/task_queue_factory.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/checks.h"
#include "rtc_base/socket_server.h"
#include "rtc_base/synchronization/yield_policy.h"
#include "rtc_base/thread.h"
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/clock.h"
#include "test/time_controller/simulated_thread.h"

namespace webrtc {

GlobalSimulatedTimeController::GlobalSimulatedTimeController(
    Timestamp start_time,
    SocketServer* socket_server)
    : sim_clock_(start_time.us()), impl_(start_time), yield_policy_(&impl_) {
  global_clock_.SetTime(start_time);
  std::unique_ptr<SimulatedMainThread> main_thread;
  if (socket_server) {
    main_thread = std::make_unique<SimulatedMainThread>(&impl_, socket_server);
  } else {
    main_thread = std::make_unique<SimulatedMainThread>(&impl_);
  }
  impl_.Register(main_thread.get());
  main_thread_ = std::move(main_thread);
}

GlobalSimulatedTimeController::~GlobalSimulatedTimeController() = default;

Clock* GlobalSimulatedTimeController::GetClock() {
  return &sim_clock_;
}

TaskQueueFactory* GlobalSimulatedTimeController::GetTaskQueueFactory() {
  return &impl_;
}

std::unique_ptr<Thread> GlobalSimulatedTimeController::CreateThread(
    const std::string& name,
    std::unique_ptr<SocketServer> socket_server) {
  return impl_.CreateThread(name, std::move(socket_server));
}

Thread* GlobalSimulatedTimeController::GetMainThread() {
  return main_thread_.get();
}

void GlobalSimulatedTimeController::AdvanceTime(TimeDelta duration) {
  ScopedYieldPolicy yield_policy(&impl_);
  Timestamp current_time = impl_.CurrentTime();
  RTC_DCHECK_EQ(current_time, sim_clock_.CurrentTime());
  RTC_DCHECK_EQ(current_time.us(), TimeMicros());
  Timestamp target_time = current_time + duration;
  while (current_time < target_time) {
    impl_.RunReadyRunners();
    Timestamp next_time = std::min(impl_.NextRunTime(), target_time);
    impl_.AdvanceTime(next_time);
    auto delta = next_time - current_time;
    current_time = next_time;
    sim_clock_.AdvanceTimeMicroseconds(delta.us());
    global_clock_.AdvanceTime(delta);
  }
  // After time has been simulated up until `target_time` we also need to run
  // tasks meant to be executed at `target_time`.
  impl_.RunReadyRunners();
}

void GlobalSimulatedTimeController::SkipForwardBy(TimeDelta duration) {
  ScopedYieldPolicy yield_policy(&impl_);
  Timestamp current_time = impl_.CurrentTime();
  Timestamp target_time = current_time + duration;
  impl_.AdvanceTime(target_time);
  sim_clock_.AdvanceTimeMicroseconds(duration.us());
  global_clock_.AdvanceTime(duration);
}

}  // namespace webrtc
