/*
 *  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 "modules/video_coding/codecs/test/video_codec_tester_impl.h"

#include <memory>
#include <tuple>
#include <utility>
#include <vector>

#include "api/units/frequency.h"
#include "api/units/time_delta.h"
#include "api/video/encoded_image.h"
#include "api/video/i420_buffer.h"
#include "api/video/video_frame.h"
#include "rtc_base/fake_clock.h"
#include "rtc_base/gunit.h"
#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/time_utils.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace test {

namespace {
using ::testing::_;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::Return;

using Decoder = VideoCodecTester::Decoder;
using Encoder = VideoCodecTester::Encoder;
using CodedVideoSource = VideoCodecTester::CodedVideoSource;
using RawVideoSource = VideoCodecTester::RawVideoSource;
using DecoderSettings = VideoCodecTester::DecoderSettings;
using EncoderSettings = VideoCodecTester::EncoderSettings;
using PacingSettings = VideoCodecTester::PacingSettings;
using PacingMode = PacingSettings::PacingMode;

constexpr Frequency k90kHz = Frequency::Hertz(90000);

struct PacingTestParams {
  PacingSettings pacing_settings;
  Frequency framerate;
  int num_frames;
  std::vector<int> expected_delta_ms;
};

VideoFrame CreateVideoFrame(uint32_t timestamp_rtp) {
  rtc::scoped_refptr<I420Buffer> buffer(I420Buffer::Create(2, 2));
  return VideoFrame::Builder()
      .set_video_frame_buffer(buffer)
      .set_timestamp_rtp(timestamp_rtp)
      .build();
}

EncodedImage CreateEncodedImage(uint32_t timestamp_rtp) {
  EncodedImage encoded_image;
  encoded_image.SetTimestamp(timestamp_rtp);
  return encoded_image;
}

class MockRawVideoSource : public RawVideoSource {
 public:
  MockRawVideoSource(int num_frames, Frequency framerate)
      : num_frames_(num_frames), frame_num_(0), framerate_(framerate) {}

  absl::optional<VideoFrame> PullFrame() override {
    if (frame_num_ >= num_frames_) {
      return absl::nullopt;
    }
    uint32_t timestamp_rtp = frame_num_ * k90kHz / framerate_;
    ++frame_num_;
    return CreateVideoFrame(timestamp_rtp);
  }

  MOCK_METHOD(VideoFrame,
              GetFrame,
              (uint32_t timestamp_rtp, Resolution),
              (override));

 private:
  int num_frames_;
  int frame_num_;
  Frequency framerate_;
};

class MockCodedVideoSource : public CodedVideoSource {
 public:
  MockCodedVideoSource(int num_frames, Frequency framerate)
      : num_frames_(num_frames), frame_num_(0), framerate_(framerate) {}

  absl::optional<EncodedImage> PullFrame() override {
    if (frame_num_ >= num_frames_) {
      return absl::nullopt;
    }
    uint32_t timestamp_rtp = frame_num_ * k90kHz / framerate_;
    ++frame_num_;
    return CreateEncodedImage(timestamp_rtp);
  }

 private:
  int num_frames_;
  int frame_num_;
  Frequency framerate_;
};

class MockDecoder : public Decoder {
 public:
  MOCK_METHOD(void, Initialize, (), (override));
  MOCK_METHOD(void,
              Decode,
              (const EncodedImage& frame, DecodeCallback callback),
              (override));
  MOCK_METHOD(void, Flush, (), (override));
};

class MockEncoder : public Encoder {
 public:
  MOCK_METHOD(void, Initialize, (), (override));
  MOCK_METHOD(void,
              Encode,
              (const VideoFrame& frame, EncodeCallback callback),
              (override));
  MOCK_METHOD(void, Flush, (), (override));
};

}  // namespace

class VideoCodecTesterImplPacingTest
    : public ::testing::TestWithParam<PacingTestParams> {
 public:
  VideoCodecTesterImplPacingTest() : test_params_(GetParam()) {}

 protected:
  PacingTestParams test_params_;
};

TEST_P(VideoCodecTesterImplPacingTest, PaceEncode) {
  MockRawVideoSource video_source(test_params_.num_frames,
                                  test_params_.framerate);
  MockEncoder encoder;
  EncoderSettings encoder_settings;
  encoder_settings.pacing = test_params_.pacing_settings;

  VideoCodecTesterImpl tester;
  auto fs =
      tester.RunEncodeTest(&video_source, &encoder, encoder_settings)->Slice();
  ASSERT_EQ(static_cast<int>(fs.size()), test_params_.num_frames);

  for (size_t i = 1; i < fs.size(); ++i) {
    int delta_ms = (fs[i].encode_start - fs[i - 1].encode_start).ms();
    EXPECT_NEAR(delta_ms, test_params_.expected_delta_ms[i - 1], 10);
  }
}

TEST_P(VideoCodecTesterImplPacingTest, PaceDecode) {
  MockCodedVideoSource video_source(test_params_.num_frames,
                                    test_params_.framerate);
  MockDecoder decoder;
  DecoderSettings decoder_settings;
  decoder_settings.pacing = test_params_.pacing_settings;

  VideoCodecTesterImpl tester;
  auto fs =
      tester.RunDecodeTest(&video_source, &decoder, decoder_settings)->Slice();
  ASSERT_EQ(static_cast<int>(fs.size()), test_params_.num_frames);

  for (size_t i = 1; i < fs.size(); ++i) {
    int delta_ms = (fs[i].decode_start - fs[i - 1].decode_start).ms();
    EXPECT_NEAR(delta_ms, test_params_.expected_delta_ms[i - 1], 20);
  }
}

INSTANTIATE_TEST_SUITE_P(
    DISABLED_All,
    VideoCodecTesterImplPacingTest,
    ::testing::ValuesIn(
        {// No pacing.
         PacingTestParams({.pacing_settings = {.mode = PacingMode::kNoPacing},
                           .framerate = Frequency::Hertz(10),
                           .num_frames = 3,
                           .expected_delta_ms = {0, 0}}),
         // Real-time pacing.
         PacingTestParams({.pacing_settings = {.mode = PacingMode::kRealTime},
                           .framerate = Frequency::Hertz(10),
                           .num_frames = 3,
                           .expected_delta_ms = {100, 100}}),
         // Pace with specified constant rate.
         PacingTestParams(
             {.pacing_settings = {.mode = PacingMode::kConstantRate,
                                  .constant_rate = Frequency::Hertz(20)},
              .framerate = Frequency::Hertz(10),
              .num_frames = 3,
              .expected_delta_ms = {50, 50}})}));
}  // namespace test
}  // namespace webrtc
