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

#ifndef RTC_BASE_TASK_UTILS_REPEATING_TASK_H_
#define RTC_BASE_TASK_UTILS_REPEATING_TASK_H_

#include <memory>
#include <type_traits>
#include <utility>

#include "api/task_queue/pending_task_safety_flag.h"
#include "api/task_queue/queued_task.h"
#include "api/task_queue/task_queue_base.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "system_wrappers/include/clock.h"

namespace webrtc {

namespace webrtc_repeating_task_impl {

// Methods simplifying external tracing of RepeatingTaskHandle operations.
void RepeatingTaskHandleDTraceProbeStart();
void RepeatingTaskHandleDTraceProbeDelayedStart();
void RepeatingTaskImplDTraceProbeRun();

class RepeatingTaskBase : public QueuedTask {
 public:
  RepeatingTaskBase(TaskQueueBase* task_queue,
                    TaskQueueBase::DelayPrecision precision,
                    TimeDelta first_delay,
                    Clock* clock,
                    rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag);
  ~RepeatingTaskBase() override;

 private:
  virtual TimeDelta RunClosure() = 0;

  bool Run() final;

  TaskQueueBase* const task_queue_;
  const TaskQueueBase::DelayPrecision precision_;
  Clock* const clock_;
  // This is always finite.
  Timestamp next_run_time_ RTC_GUARDED_BY(task_queue_);
  rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag_
      RTC_GUARDED_BY(task_queue_);
};

// The template closure pattern is based on rtc::ClosureTask. The provided
// closure should have a TimeDelta return value, specifing the desired
// non-negative interval to next repetition, or TimeDelta::PlusInfinity to
// indicate that the task should be deleted and not called again.
template <class Closure>
class RepeatingTaskImpl final : public RepeatingTaskBase {
 public:
  RepeatingTaskImpl(TaskQueueBase* task_queue,
                    TaskQueueBase::DelayPrecision precision,
                    TimeDelta first_delay,
                    Closure&& closure,
                    Clock* clock,
                    rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag)
      : RepeatingTaskBase(task_queue,
                          precision,
                          first_delay,
                          clock,
                          std::move(alive_flag)),
        closure_(std::forward<Closure>(closure)) {
    static_assert(
        std::is_same<TimeDelta,
                     typename std::invoke_result<decltype(&Closure::operator()),
                                                 Closure>::type>::value,
        "");
  }

 private:
  TimeDelta RunClosure() override {
    RepeatingTaskImplDTraceProbeRun();
    return closure_();
  }

  typename std::remove_const<
      typename std::remove_reference<Closure>::type>::type closure_;
};
}  // namespace webrtc_repeating_task_impl

// Allows starting tasks that repeat themselves on a TaskQueue indefinately
// until they are stopped or the TaskQueue is destroyed. It allows starting and
// stopping multiple times, but you must stop one task before starting another
// and it can only be stopped when in the running state. The public interface is
// not thread safe.
class RepeatingTaskHandle {
 public:
  RepeatingTaskHandle() = default;
  ~RepeatingTaskHandle() = default;
  RepeatingTaskHandle(RepeatingTaskHandle&& other) = default;
  RepeatingTaskHandle& operator=(RepeatingTaskHandle&& other) = default;
  RepeatingTaskHandle(const RepeatingTaskHandle&) = delete;
  RepeatingTaskHandle& operator=(const RepeatingTaskHandle&) = delete;

  // Start can be used to start a task that will be reposted with a delay
  // determined by the return value of the provided closure. The actual task is
  // owned by the TaskQueue and will live until it has been stopped or the
  // TaskQueue deletes it. It's perfectly fine to destroy the handle while the
  // task is running, since the repeated task is owned by the TaskQueue.
  // The tasks are scheduled onto the task queue using the specified precision.
  template <class Closure>
  static RepeatingTaskHandle Start(TaskQueueBase* task_queue,
                                   Closure&& closure,
                                   TaskQueueBase::DelayPrecision precision =
                                       TaskQueueBase::DelayPrecision::kLow,
                                   Clock* clock = Clock::GetRealTimeClock()) {
    auto alive_flag = PendingTaskSafetyFlag::CreateDetached();
    webrtc_repeating_task_impl::RepeatingTaskHandleDTraceProbeStart();
    task_queue->PostTask(
        std::make_unique<
            webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
            task_queue, precision, TimeDelta::Zero(),
            std::forward<Closure>(closure), clock, alive_flag));
    return RepeatingTaskHandle(std::move(alive_flag));
  }

  // DelayedStart is equivalent to Start except that the first invocation of the
  // closure will be delayed by the given amount.
  template <class Closure>
  static RepeatingTaskHandle DelayedStart(
      TaskQueueBase* task_queue,
      TimeDelta first_delay,
      Closure&& closure,
      TaskQueueBase::DelayPrecision precision =
          TaskQueueBase::DelayPrecision::kLow,
      Clock* clock = Clock::GetRealTimeClock()) {
    auto alive_flag = PendingTaskSafetyFlag::CreateDetached();
    webrtc_repeating_task_impl::RepeatingTaskHandleDTraceProbeDelayedStart();
    task_queue->PostDelayedTaskWithPrecision(
        precision,
        std::make_unique<
            webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
            task_queue, precision, first_delay, std::forward<Closure>(closure),
            clock, alive_flag),
        first_delay.ms());
    return RepeatingTaskHandle(std::move(alive_flag));
  }

  // Stops future invocations of the repeating task closure. Can only be called
  // from the TaskQueue where the task is running. The closure is guaranteed to
  // not be running after Stop() returns unless Stop() is called from the
  // closure itself.
  void Stop();

  // Returns true until Stop() was called.
  // Can only be called from the TaskQueue where the task is running.
  bool Running() const;

 private:
  explicit RepeatingTaskHandle(
      rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag)
      : repeating_task_(std::move(alive_flag)) {}
  rtc::scoped_refptr<PendingTaskSafetyFlag> repeating_task_;
};

}  // namespace webrtc
#endif  // RTC_BASE_TASK_UTILS_REPEATING_TASK_H_
