/*
 *  Copyright (c) 2022 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 "video/video_receive_stream_timeout_tracker.h"

#include <algorithm>
#include <utility>

#include "rtc_base/logging.h"

namespace webrtc {

VideoReceiveStreamTimeoutTracker::VideoReceiveStreamTimeoutTracker(
    Clock* clock,
    TaskQueueBase* const bookkeeping_queue,
    const Timeouts& timeouts,
    TimeoutCallback callback)
    : clock_(clock),
      bookkeeping_queue_(bookkeeping_queue),
      timeouts_(timeouts),
      timeout_cb_(std::move(callback)) {}

VideoReceiveStreamTimeoutTracker::~VideoReceiveStreamTimeoutTracker() {
  RTC_DCHECK(!timeout_task_.Running());
}

bool VideoReceiveStreamTimeoutTracker::Running() const {
  return timeout_task_.Running();
}

TimeDelta VideoReceiveStreamTimeoutTracker::TimeUntilTimeout() const {
  return std::max(timeout_ - clock_->CurrentTime(), TimeDelta::Zero());
}

void VideoReceiveStreamTimeoutTracker::Start(bool waiting_for_keyframe) {
  RTC_DCHECK(!timeout_task_.Running());
  waiting_for_keyframe_ = waiting_for_keyframe;
  TimeDelta timeout_delay = TimeoutForNextFrame();
  last_frame_ = clock_->CurrentTime();
  timeout_ = last_frame_ + timeout_delay;
  timeout_task_ =
      RepeatingTaskHandle::DelayedStart(bookkeeping_queue_, timeout_delay,
                                        [this] { return HandleTimeoutTask(); });
}

void VideoReceiveStreamTimeoutTracker::Stop() {
  timeout_task_.Stop();
}

void VideoReceiveStreamTimeoutTracker::SetWaitingForKeyframe() {
  waiting_for_keyframe_ = true;
  TimeDelta timeout_delay = TimeoutForNextFrame();
  if (clock_->CurrentTime() + timeout_delay < timeout_) {
    Stop();
    Start(waiting_for_keyframe_);
  }
}

void VideoReceiveStreamTimeoutTracker::OnEncodedFrameReleased() {
  // If we were waiting for a keyframe, then it has just been released.
  waiting_for_keyframe_ = false;
  last_frame_ = clock_->CurrentTime();
  timeout_ = last_frame_ + TimeoutForNextFrame();
}

TimeDelta VideoReceiveStreamTimeoutTracker::HandleTimeoutTask() {
  Timestamp now = clock_->CurrentTime();
  // `timeout_` is hit and we have timed out. Schedule the next timeout at
  // the timeout delay.
  if (now >= timeout_) {
    RTC_DLOG(LS_VERBOSE) << "Stream timeout at " << now;
    TimeDelta timeout_delay = TimeoutForNextFrame();
    timeout_ = now + timeout_delay;
    timeout_cb_(now - last_frame_);
    return timeout_delay;
  }
  // Otherwise, `timeout_` changed since we scheduled a timeout. Reschedule
  // a timeout check.
  return timeout_ - now;
}

}  // namespace webrtc
