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

#include <stdint.h>

#include <optional>

#include "api/units/time_delta.h"
#include "modules/video_coding/timing/timing.h"
#include "rtc_base/containers/flat_map.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/scoped_key_value_config.h"
#include "video/video_receive_stream2.h"

namespace webrtc {

using ::testing::AllOf;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Optional;

namespace {

class FakeVCMTiming : public webrtc::VCMTiming {
 public:
  explicit FakeVCMTiming(Clock* clock, const FieldTrialsView& field_trials)
      : webrtc::VCMTiming(clock, field_trials) {}

  Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
    RTC_DCHECK(render_time_map_.contains(frame_timestamp));
    auto it = render_time_map_.find(frame_timestamp);
    return it->second;
  }

  TimeDelta MaxWaitingTime(Timestamp render_time,
                           Timestamp now,
                           bool too_many_frames_queued) const override {
    RTC_DCHECK(wait_time_map_.contains(render_time));
    auto it = wait_time_map_.find(render_time);
    return it->second;
  }

  void SetTimes(uint32_t frame_timestamp,
                Timestamp render_time,
                TimeDelta max_decode_wait) {
    render_time_map_.insert_or_assign(frame_timestamp, render_time);
    wait_time_map_.insert_or_assign(render_time, max_decode_wait);
  }

 protected:
  flat_map<uint32_t, Timestamp> render_time_map_;
  flat_map<Timestamp, TimeDelta> wait_time_map_;
};
}  // namespace

class FrameDecodeTimingTest : public ::testing::Test {
 public:
  FrameDecodeTimingTest()
      : clock_(Timestamp::Millis(1000)),
        timing_(&clock_, field_trials_),
        frame_decode_scheduler_(&clock_, &timing_) {}

 protected:
  test::ScopedKeyValueConfig field_trials_;
  SimulatedClock clock_;
  FakeVCMTiming timing_;
  FrameDecodeTiming frame_decode_scheduler_;
};

TEST_F(FrameDecodeTimingTest, ReturnsWaitTimesWhenValid) {
  const TimeDelta decode_delay = TimeDelta::Millis(42);
  const Timestamp render_time = clock_.CurrentTime() + TimeDelta::Millis(60);
  timing_.SetTimes(90000, render_time, decode_delay);

  EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
                  90000, 180000, kMaxWaitForFrame, false),
              Optional(AllOf(
                  Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
                        Eq(clock_.CurrentTime() + decode_delay)),
                  Field(&FrameDecodeTiming::FrameSchedule::render_time,
                        Eq(render_time)))));
}

TEST_F(FrameDecodeTimingTest, FastForwardsFrameTooFarInThePast) {
  const TimeDelta decode_delay =
      -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
  const Timestamp render_time = clock_.CurrentTime();
  timing_.SetTimes(90000, render_time, decode_delay);

  EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
                  90000, 180000, kMaxWaitForFrame, false),
              Eq(std::nullopt));
}

TEST_F(FrameDecodeTimingTest, NoFastForwardIfOnlyFrameToDecode) {
  const TimeDelta decode_delay =
      -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
  const Timestamp render_time = clock_.CurrentTime();
  timing_.SetTimes(90000, render_time, decode_delay);

  // Negative `decode_delay` means that `latest_decode_time` is now.
  EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
                  90000, 90000, kMaxWaitForFrame, false),
              Optional(AllOf(
                  Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
                        Eq(clock_.CurrentTime())),
                  Field(&FrameDecodeTiming::FrameSchedule::render_time,
                        Eq(render_time)))));
}

TEST_F(FrameDecodeTimingTest, MaxWaitCapped) {
  TimeDelta frame_delay = TimeDelta::Millis(30);
  const TimeDelta decode_delay = TimeDelta::Seconds(3);
  const Timestamp render_time = clock_.CurrentTime() + TimeDelta::Seconds(3);
  timing_.SetTimes(90000, render_time, decode_delay);
  timing_.SetTimes(180000, render_time + frame_delay,
                   decode_delay + frame_delay);

  EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
                  90000, 270000, kMaxWaitForFrame, false),
              Optional(AllOf(
                  Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
                        Eq(clock_.CurrentTime() + kMaxWaitForFrame)),
                  Field(&FrameDecodeTiming::FrameSchedule::render_time,
                        Eq(render_time)))));

  // Test cap keyframe.
  clock_.AdvanceTime(frame_delay);
  EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
                  180000, 270000, kMaxWaitForKeyFrame, false),
              Optional(AllOf(
                  Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
                        Eq(clock_.CurrentTime() + kMaxWaitForKeyFrame)),
                  Field(&FrameDecodeTiming::FrameSchedule::render_time,
                        Eq(render_time + frame_delay)))));
}

}  // namespace webrtc
