/*
 *  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/task_queue_frame_decode_scheduler.h"

#include <stddef.h>

#include <memory>
#include <utility>

#include "absl/functional/bind_front.h"
#include "absl/types/optional.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/task_queue.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/time_controller/simulated_time_controller.h"

namespace webrtc {

using ::testing::Eq;
using ::testing::Optional;

class TaskQueueFrameDecodeSchedulerTest : public ::testing::Test {
 public:
  TaskQueueFrameDecodeSchedulerTest()
      : time_controller_(Timestamp::Millis(2000)),
        task_queue_(time_controller_.GetTaskQueueFactory()->CreateTaskQueue(
            "scheduler",
            TaskQueueFactory::Priority::NORMAL)),
        scheduler_(std::make_unique<TaskQueueFrameDecodeScheduler>(
            time_controller_.GetClock(),
            task_queue_.Get())) {}

  ~TaskQueueFrameDecodeSchedulerTest() override {
    if (scheduler_) {
      OnQueue([&] {
        scheduler_->Stop();
        scheduler_ = nullptr;
      });
    }
  }

  void FrameReadyForDecode(uint32_t timestamp, Timestamp render_time) {
    last_rtp_ = timestamp;
    last_render_time_ = render_time;
  }

 protected:
  template <class Task>
  void OnQueue(Task&& t) {
    task_queue_.PostTask(std::forward<Task>(t));
    time_controller_.AdvanceTime(TimeDelta::Zero());
  }

  GlobalSimulatedTimeController time_controller_;
  rtc::TaskQueue task_queue_;
  std::unique_ptr<FrameDecodeScheduler> scheduler_;
  absl::optional<uint32_t> last_rtp_;
  absl::optional<Timestamp> last_render_time_;
};

TEST_F(TaskQueueFrameDecodeSchedulerTest, FrameYieldedAfterSpecifiedPeriod) {
  constexpr TimeDelta decode_delay = TimeDelta::Millis(5);
  const Timestamp now = time_controller_.GetClock()->CurrentTime();
  const uint32_t rtp = 90000;
  const Timestamp render_time = now + TimeDelta::Millis(15);
  FrameDecodeTiming::FrameSchedule schedule = {
      .latest_decode_time = now + decode_delay, .render_time = render_time};
  OnQueue([&] {
    scheduler_->ScheduleFrame(
        rtp, schedule,
        absl::bind_front(
            &TaskQueueFrameDecodeSchedulerTest::FrameReadyForDecode, this));
    EXPECT_THAT(scheduler_->ScheduledRtpTimestamp(), Optional(rtp));
  });
  EXPECT_THAT(last_rtp_, Eq(absl::nullopt));

  time_controller_.AdvanceTime(decode_delay);
  EXPECT_THAT(last_rtp_, Optional(rtp));
  EXPECT_THAT(last_render_time_, Optional(render_time));
}

TEST_F(TaskQueueFrameDecodeSchedulerTest, NegativeDecodeDelayIsRoundedToZero) {
  constexpr TimeDelta decode_delay = TimeDelta::Millis(-5);
  const Timestamp now = time_controller_.GetClock()->CurrentTime();
  const uint32_t rtp = 90000;
  const Timestamp render_time = now + TimeDelta::Millis(15);
  FrameDecodeTiming::FrameSchedule schedule = {
      .latest_decode_time = now + decode_delay, .render_time = render_time};
  OnQueue([&] {
    scheduler_->ScheduleFrame(
        rtp, schedule,
        absl::bind_front(
            &TaskQueueFrameDecodeSchedulerTest::FrameReadyForDecode, this));
    EXPECT_THAT(scheduler_->ScheduledRtpTimestamp(), Optional(rtp));
  });
  EXPECT_THAT(last_rtp_, Optional(rtp));
  EXPECT_THAT(last_render_time_, Optional(render_time));
}

TEST_F(TaskQueueFrameDecodeSchedulerTest, CancelOutstanding) {
  constexpr TimeDelta decode_delay = TimeDelta::Millis(50);
  const Timestamp now = time_controller_.GetClock()->CurrentTime();
  const uint32_t rtp = 90000;
  FrameDecodeTiming::FrameSchedule schedule = {
      .latest_decode_time = now + decode_delay,
      .render_time = now + TimeDelta::Millis(75)};
  OnQueue([&] {
    scheduler_->ScheduleFrame(
        rtp, schedule,
        absl::bind_front(
            &TaskQueueFrameDecodeSchedulerTest::FrameReadyForDecode, this));
    EXPECT_THAT(scheduler_->ScheduledRtpTimestamp(), Optional(rtp));
  });
  time_controller_.AdvanceTime(decode_delay / 2);
  OnQueue([&] {
    EXPECT_THAT(scheduler_->ScheduledRtpTimestamp(), Optional(rtp));
    scheduler_->CancelOutstanding();
    EXPECT_THAT(scheduler_->ScheduledRtpTimestamp(), Eq(absl::nullopt));
  });
  time_controller_.AdvanceTime(decode_delay / 2);
  EXPECT_THAT(last_rtp_, Eq(absl::nullopt));
  EXPECT_THAT(last_render_time_, Eq(absl::nullopt));
}

}  // namespace webrtc
