/*
 *  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/task_queue/task_queue_factory.h"
#include "api/task_queue/test/mock_task_queue_base.h"
#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,
              Decode,
              (const EncodedImage& frame, DecodeCallback callback),
              (override));
  MOCK_METHOD(void, Flush, (), (override));
};

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

class MockTaskQueueFactory : public TaskQueueFactory {
 public:
  explicit MockTaskQueueFactory(TaskQueueBase& task_queue)
      : task_queue_(task_queue) {}

  std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
      absl::string_view name,
      Priority priority) const override {
    return std::unique_ptr<TaskQueueBase, TaskQueueDeleter>(&task_queue_);
  }

 protected:
  TaskQueueBase& task_queue_;
};
}  // 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
