/*
 *  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/queued_task.h"
#include "api/task_queue/task_queue_base.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/task_utils/pending_task_safety_flag.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_
