/*
 *  Copyright 2018 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.
 */

#ifndef RTC_BASE_TASK_QUEUE_FOR_TEST_H_
#define RTC_BASE_TASK_QUEUE_FOR_TEST_H_

#include <memory>
#include <utility>

#include "absl/cleanup/cleanup.h"
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/function_view.h"
#include "api/location.h"
#include "api/task_queue/task_queue_base.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/units/time_delta.h"
#include "rtc_base/checks.h"
#include "rtc_base/event.h"

namespace webrtc {

inline void SendTask(TaskQueueBase* task_queue, FunctionView<void()> task) {
  if (task_queue->IsCurrent()) {
    task();
    return;
  }

  Event event;
  absl::Cleanup cleanup = [&event] { event.Set(); };
  task_queue->PostTask([task, cleanup = std::move(cleanup)] { task(); });
  RTC_CHECK(event.Wait(/*give_up_after=*/Event::kForever,
                       /*warn_after=*/TimeDelta::Seconds(10)));
}

class TaskQueueForTest {
 public:
  explicit TaskQueueForTest(
      std::unique_ptr<TaskQueueBase, TaskQueueDeleter> task_queue);
  explicit TaskQueueForTest(
      absl::string_view name = "TestQueue",
      TaskQueueFactory::Priority priority = TaskQueueFactory::Priority::NORMAL);
  TaskQueueForTest(const TaskQueueForTest&) = delete;
  TaskQueueForTest& operator=(const TaskQueueForTest&) = delete;
  ~TaskQueueForTest();

  bool IsCurrent() const { return impl_->IsCurrent(); }

  // Returns non-owning pointer to the task queue implementation.
  TaskQueueBase* Get() { return impl_.get(); }

  void PostTask(absl::AnyInvocable<void() &&> task,
                const Location& location = Location::Current()) {
    impl_->PostTask(std::move(task), location);
  }
  void PostDelayedTask(absl::AnyInvocable<void() &&> task,
                       TimeDelta delay,
                       const Location& location = Location::Current()) {
    impl_->PostDelayedTask(std::move(task), delay, location);
  }
  void PostDelayedHighPrecisionTask(
      absl::AnyInvocable<void() &&> task,
      TimeDelta delay,
      const Location& location = Location::Current()) {
    impl_->PostDelayedHighPrecisionTask(std::move(task), delay, location);
  }

  // A convenience, test-only method that blocks the current thread while
  // a task executes on the task queue.
  void SendTask(FunctionView<void()> task) { ::webrtc::SendTask(Get(), task); }

  // Wait for the completion of all tasks posted prior to the
  // WaitForPreviouslyPostedTasks() call.
  void WaitForPreviouslyPostedTasks() {
    RTC_DCHECK(!Get()->IsCurrent());
    // Post an empty task on the queue and wait for it to finish, to ensure
    // that all already posted tasks on the queue get executed.
    SendTask([]() {});
  }

 private:
  std::unique_ptr<TaskQueueBase, TaskQueueDeleter> impl_;
};

}  // namespace webrtc

#endif  // RTC_BASE_TASK_QUEUE_FOR_TEST_H_
