/*
 *  Copyright (c) 2020 The WebM 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 <cstdint>
#include <new>

#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/yuv_video_source.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "vpx/vpx_ext_ratectrl.h"

namespace {

constexpr int kModelMagicNumber = 51396;
constexpr uintptr_t PrivMagicNumber = 5566;
constexpr int kFrameNum = 5;
constexpr int kLosslessCodingIndex = 2;

struct ToyRateCtrl {
  int magic_number;
  int coding_index;
};

vpx_rc_status_t rc_create_model(void *priv,
                                const vpx_rc_config_t *ratectrl_config,
                                vpx_rc_model_t *rate_ctrl_model_pt) {
  ToyRateCtrl *toy_rate_ctrl = new (std::nothrow) ToyRateCtrl;
  EXPECT_NE(toy_rate_ctrl, nullptr);
  toy_rate_ctrl->magic_number = kModelMagicNumber;
  toy_rate_ctrl->coding_index = -1;
  *rate_ctrl_model_pt = toy_rate_ctrl;
  EXPECT_EQ(priv, reinterpret_cast<void *>(PrivMagicNumber));
  EXPECT_EQ(ratectrl_config->frame_width, 352);
  EXPECT_EQ(ratectrl_config->frame_height, 288);
  EXPECT_EQ(ratectrl_config->show_frame_count, kFrameNum);
  EXPECT_EQ(ratectrl_config->target_bitrate_kbps, 24000);
  EXPECT_EQ(ratectrl_config->frame_rate_num, 30);
  EXPECT_EQ(ratectrl_config->frame_rate_den, 1);
  return VPX_RC_OK;
}

vpx_rc_status_t rc_send_firstpass_stats(
    vpx_rc_model_t rate_ctrl_model,
    const vpx_rc_firstpass_stats_t *first_pass_stats) {
  const ToyRateCtrl *toy_rate_ctrl =
      static_cast<ToyRateCtrl *>(rate_ctrl_model);
  EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);
  EXPECT_EQ(first_pass_stats->num_frames, kFrameNum);
  for (int i = 0; i < first_pass_stats->num_frames; ++i) {
    EXPECT_DOUBLE_EQ(first_pass_stats->frame_stats[i].frame, i);
  }
  return VPX_RC_OK;
}

vpx_rc_status_t rc_get_encodeframe_decision(
    vpx_rc_model_t rate_ctrl_model,
    const vpx_rc_encodeframe_info_t *encode_frame_info,
    vpx_rc_encodeframe_decision_t *frame_decision) {
  ToyRateCtrl *toy_rate_ctrl = static_cast<ToyRateCtrl *>(rate_ctrl_model);
  toy_rate_ctrl->coding_index += 1;

  EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);

  EXPECT_LT(encode_frame_info->show_index, kFrameNum);
  EXPECT_EQ(encode_frame_info->coding_index, toy_rate_ctrl->coding_index);

  if (encode_frame_info->coding_index == 0) {
    EXPECT_EQ(encode_frame_info->show_index, 0);
    EXPECT_EQ(encode_frame_info->gop_index, 0);
    EXPECT_EQ(encode_frame_info->frame_type, 0 /*kFrameTypeKey*/);
    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0],
              0);  // kRefFrameTypeLast
    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1],
              0);  // kRefFrameTypePast
    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2],
              0);  // kRefFrameTypeFuture
  }

  if (encode_frame_info->coding_index == 1) {
    EXPECT_EQ(encode_frame_info->show_index, 4);
    EXPECT_EQ(encode_frame_info->gop_index, 1);
    EXPECT_EQ(encode_frame_info->frame_type, 2 /*kFrameTypeAltRef*/);
    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0],
              1);  // kRefFrameTypeLast
    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1],
              0);  // kRefFrameTypePast
    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2],
              0);  // kRefFrameTypeFuture
    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[0],
              0);  // kRefFrameTypeLast
  }

  if (encode_frame_info->coding_index >= 2 &&
      encode_frame_info->coding_index < 5) {
    // In the first group of pictures, coding_index and gop_index are equal.
    EXPECT_EQ(encode_frame_info->gop_index, encode_frame_info->coding_index);
    EXPECT_EQ(encode_frame_info->frame_type, 1 /*kFrameTypeInter*/);
  }

  if (encode_frame_info->coding_index == 5) {
    EXPECT_EQ(encode_frame_info->show_index, 4);
    EXPECT_EQ(encode_frame_info->gop_index, 0);
    EXPECT_EQ(encode_frame_info->frame_type, 3 /*kFrameTypeOverlay*/);
    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0],
              1);  // kRefFrameTypeLast
    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1],
              1);  // kRefFrameTypePast
    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2],
              1);  // kRefFrameTypeFuture
    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[0],
              4);  // kRefFrameTypeLast
    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[1],
              0);  // kRefFrameTypePast
    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[2],
              1);  // kRefFrameTypeFuture
  }
  if (encode_frame_info->coding_index == kLosslessCodingIndex) {
    // We should get sse == 0 at rc_update_encodeframe_result()
    frame_decision->q_index = 0;
  } else {
    frame_decision->q_index = 100;
  }
  frame_decision->max_frame_size = 0;
  return VPX_RC_OK;
}

vpx_rc_status_t rc_update_encodeframe_result(
    vpx_rc_model_t rate_ctrl_model,
    const vpx_rc_encodeframe_result_t *encode_frame_result) {
  const ToyRateCtrl *toy_rate_ctrl =
      static_cast<ToyRateCtrl *>(rate_ctrl_model);
  EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);

  const int64_t ref_pixel_count = 352 * 288 * 3 / 2;
  EXPECT_EQ(encode_frame_result->pixel_count, ref_pixel_count);
  if (toy_rate_ctrl->coding_index == kLosslessCodingIndex) {
    EXPECT_EQ(encode_frame_result->sse, 0);
  }
  if (toy_rate_ctrl->coding_index == kLosslessCodingIndex) {
    EXPECT_EQ(encode_frame_result->actual_encoding_qindex, 0);
  } else {
    EXPECT_EQ(encode_frame_result->actual_encoding_qindex, 100);
  }
  return VPX_RC_OK;
}

vpx_rc_status_t rc_delete_model(vpx_rc_model_t rate_ctrl_model) {
  ToyRateCtrl *toy_rate_ctrl = static_cast<ToyRateCtrl *>(rate_ctrl_model);
  EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);
  delete toy_rate_ctrl;
  return VPX_RC_OK;
}

class ExtRateCtrlTest : public ::libvpx_test::EncoderTest,
                        public ::testing::Test {
 protected:
  ExtRateCtrlTest() : EncoderTest(&::libvpx_test::kVP9) {}

  ~ExtRateCtrlTest() override = default;

  void SetUp() override {
    InitializeConfig();
    SetMode(::libvpx_test::kTwoPassGood);
  }

  void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
                          ::libvpx_test::Encoder *encoder) override {
    if (video->frame() == 0) {
      vpx_rc_funcs_t rc_funcs;
      rc_funcs.create_model = rc_create_model;
      rc_funcs.send_firstpass_stats = rc_send_firstpass_stats;
      rc_funcs.get_encodeframe_decision = rc_get_encodeframe_decision;
      rc_funcs.update_encodeframe_result = rc_update_encodeframe_result;
      rc_funcs.delete_model = rc_delete_model;
      rc_funcs.priv = reinterpret_cast<void *>(PrivMagicNumber);
      encoder->Control(VP9E_SET_EXTERNAL_RATE_CONTROL, &rc_funcs);
    }
  }
};

TEST_F(ExtRateCtrlTest, EncodeTest) {
  cfg_.rc_target_bitrate = 24000;

  std::unique_ptr<libvpx_test::VideoSource> video;
  video.reset(new (std::nothrow) libvpx_test::YUVVideoSource(
      "bus_352x288_420_f20_b8.yuv", VPX_IMG_FMT_I420, 352, 288, 30, 1, 0,
      kFrameNum));

  ASSERT_NE(video.get(), nullptr);
  ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
}

}  // namespace
