/*
 *  Copyright (c) 2017 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/single_threaded_task_queue.h"

#include <memory>
#include <utility>

#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/time_utils.h"

namespace webrtc {
namespace test {

DEPRECATED_SingleThreadedTaskQueueForTesting::StoredTask::StoredTask(
    DEPRECATED_SingleThreadedTaskQueueForTesting::TaskId task_id,
    std::unique_ptr<QueuedTask> task)
    : task_id(task_id), task(std::move(task)) {}

DEPRECATED_SingleThreadedTaskQueueForTesting::StoredTask::~StoredTask() =
    default;

DEPRECATED_SingleThreadedTaskQueueForTesting::
    DEPRECATED_SingleThreadedTaskQueueForTesting(const char* name)
    : thread_(Run, this, name), running_(true), next_task_id_(0) {
  thread_.Start();
}

DEPRECATED_SingleThreadedTaskQueueForTesting::
    ~DEPRECATED_SingleThreadedTaskQueueForTesting() {
  Stop();
}

DEPRECATED_SingleThreadedTaskQueueForTesting::TaskId
DEPRECATED_SingleThreadedTaskQueueForTesting::PostDelayed(
    std::unique_ptr<QueuedTask> task,
    int64_t delay_ms) {
  int64_t earliest_exec_time = rtc::TimeAfter(delay_ms);

  rtc::CritScope lock(&cs_);
  if (!running_)
    return kInvalidTaskId;

  TaskId id = next_task_id_++;

  // Insert after any other tasks with an earlier-or-equal target time.
  // Note: multimap has promise "The order of the key-value pairs whose keys
  // compare equivalent is the order of insertion and does not change."
  tasks_.emplace(std::piecewise_construct,
                 std::forward_as_tuple(earliest_exec_time),
                 std::forward_as_tuple(id, std::move(task)));

  // This class is optimized for simplicty, not for performance. This will wake
  // the thread up even if the next task in the queue is only scheduled for
  // quite some time from now. In that case, the thread will just send itself
  // back to sleep.
  wake_up_.Set();

  return id;
}

void DEPRECATED_SingleThreadedTaskQueueForTesting::SendTask(Task task) {
  RTC_DCHECK(!IsCurrent());
  rtc::Event done;
  if (PostTask([&task, &done]() {
        task();
        done.Set();
      }) == kInvalidTaskId) {
    return;
  }
  // Give up after 30 seconds, warn after 10.
  RTC_CHECK(done.Wait(30000, 10000));
}

bool DEPRECATED_SingleThreadedTaskQueueForTesting::CancelTask(TaskId task_id) {
  rtc::CritScope lock(&cs_);
  for (auto it = tasks_.begin(); it != tasks_.end(); it++) {
    if (it->second.task_id == task_id) {
      tasks_.erase(it);
      return true;
    }
  }
  return false;
}

bool DEPRECATED_SingleThreadedTaskQueueForTesting::IsCurrent() {
  return rtc::IsThreadRefEqual(thread_.GetThreadRef(), rtc::CurrentThreadRef());
}

bool DEPRECATED_SingleThreadedTaskQueueForTesting::IsRunning() {
  RTC_DCHECK_RUN_ON(&owner_thread_checker_);
  // We could check the |running_| flag here, but this is equivalent for the
  // purposes of this function.
  return thread_.IsRunning();
}

bool DEPRECATED_SingleThreadedTaskQueueForTesting::HasPendingTasks() const {
  rtc::CritScope lock(&cs_);
  return !tasks_.empty();
}

void DEPRECATED_SingleThreadedTaskQueueForTesting::Stop() {
  RTC_DCHECK_RUN_ON(&owner_thread_checker_);
  if (!thread_.IsRunning())
    return;

  {
    rtc::CritScope lock(&cs_);
    running_ = false;
  }

  wake_up_.Set();
  thread_.Stop();
}

void DEPRECATED_SingleThreadedTaskQueueForTesting::Run(void* obj) {
  static_cast<DEPRECATED_SingleThreadedTaskQueueForTesting*>(obj)->RunLoop();
}

void DEPRECATED_SingleThreadedTaskQueueForTesting::RunLoop() {
  CurrentTaskQueueSetter set_current(this);
  while (true) {
    std::unique_ptr<QueuedTask> queued_task;

    // An empty queue would lead to sleeping until the queue becoems non-empty.
    // A queue where the earliest task is scheduled for later than now, will
    // lead to sleeping until the time of the next scheduled task (or until
    // more tasks are scheduled).
    int wait_time = rtc::Event::kForever;

    {
      rtc::CritScope lock(&cs_);
      if (!running_) {
        return;
      }
      if (!tasks_.empty()) {
        auto next_delayed_task = tasks_.begin();
        int64_t earliest_exec_time = next_delayed_task->first;
        int64_t remaining_delay_ms =
            rtc::TimeDiff(earliest_exec_time, rtc::TimeMillis());
        if (remaining_delay_ms <= 0) {
          queued_task = std::move(next_delayed_task->second.task);
          tasks_.erase(next_delayed_task);
        } else {
          wait_time = rtc::saturated_cast<int>(remaining_delay_ms);
        }
      }
    }

    if (queued_task) {
      if (!queued_task->Run()) {
        queued_task.release();
      }
    } else {
      wake_up_.Wait(wait_time);
    }
  }
}

void DEPRECATED_SingleThreadedTaskQueueForTesting::Delete() {
  Stop();
  delete this;
}

}  // namespace test
}  // namespace webrtc
