/*
 *  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 "rtc_base/task_utils/repeating_task.h"

#include "absl/memory/memory.h"
#include "rtc_base/logging.h"
#include "rtc_base/task_utils/to_queued_task.h"
#include "rtc_base/time_utils.h"

namespace webrtc {
namespace webrtc_repeating_task_impl {
RepeatingTaskBase::RepeatingTaskBase(TaskQueueBase* task_queue,
                                     TimeDelta first_delay)
    : task_queue_(task_queue),
      next_run_time_(Timestamp::us(rtc::TimeMicros()) + first_delay) {}

RepeatingTaskBase::~RepeatingTaskBase() = default;

bool RepeatingTaskBase::Run() {
  RTC_DCHECK_RUN_ON(task_queue_);
  // Return true to tell the TaskQueue to destruct this object.
  if (next_run_time_.IsPlusInfinity())
    return true;

  TimeDelta delay = RunClosure();

  // The closure might have stopped this task, in which case we return true to
  // destruct this object.
  if (next_run_time_.IsPlusInfinity())
    return true;

  RTC_DCHECK(delay.IsFinite());
  TimeDelta lost_time = Timestamp::us(rtc::TimeMicros()) - next_run_time_;
  next_run_time_ += delay;
  delay -= lost_time;
  delay = std::max(delay, TimeDelta::Zero());

  task_queue_->PostDelayedTask(absl::WrapUnique(this), delay.ms());

  // Return false to tell the TaskQueue to not destruct this object since we
  // have taken ownership with absl::WrapUnique.
  return false;
}

void RepeatingTaskBase::Stop() {
  RTC_DCHECK(next_run_time_.IsFinite());
  next_run_time_ = Timestamp::PlusInfinity();
}

}  // namespace webrtc_repeating_task_impl

RepeatingTaskHandle::RepeatingTaskHandle(RepeatingTaskHandle&& other)
    : repeating_task_(other.repeating_task_) {
  other.repeating_task_ = nullptr;
}

RepeatingTaskHandle& RepeatingTaskHandle::operator=(
    RepeatingTaskHandle&& other) {
  repeating_task_ = other.repeating_task_;
  other.repeating_task_ = nullptr;
  return *this;
}

RepeatingTaskHandle::RepeatingTaskHandle(
    webrtc_repeating_task_impl::RepeatingTaskBase* repeating_task)
    : repeating_task_(repeating_task) {}

void RepeatingTaskHandle::Stop() {
  if (repeating_task_) {
    RTC_DCHECK_RUN_ON(repeating_task_->task_queue_);
    repeating_task_->Stop();
    repeating_task_ = nullptr;
  }
}

bool RepeatingTaskHandle::Running() const {
  return repeating_task_ != nullptr;
}

}  // namespace webrtc
