/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include <unordered_map>

#include "third_party/googletest/src/googletest/include/gtest/gtest.h"

#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/y4m_video_source.h"

namespace {
const unsigned int kFrames = 10;
const int kBitrate = 500;
const unsigned int kCqLevel = 18;

// List of psnr thresholds for different test combinations
// keys: test-mode, cpu-used, sharpness.
const std::unordered_map<
    int, std::unordered_map<int, std::unordered_map<int, double>>>
    kPsnrThreshold = { { static_cast<int>(::libaom_test::kTwoPassGood),
                         { { 2, { { 2, 37.6 }, { 5, 37.6 } } },
                           { 4, { { 2, 37.5 }, { 5, 37.5 } } },
                           { 6, { { 2, 37.5 }, { 5, 37.5 } } } } },
                       { static_cast<int>(::libaom_test::kAllIntra),
                         { { 3, { { 2, 42.2 }, { 5, 42.2 } } },
                           { 6, { { 2, 41.8 }, { 4, 41.9 }, { 5, 41.9 } } },
                           { 9, { { 2, 41.0 }, { 5, 41.0 } } } } } };

// This class is used to test sharpness parameter configured through control
// call using AOME_SET_SHARPNESS for different encoder configurations.
class SharpnessTest
    : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode, int,
                                                 int>,
      public ::libaom_test::EncoderTest {
 protected:
  SharpnessTest()
      : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
        cpu_used_(GET_PARAM(2)), sharpness_level_(GET_PARAM(3)), psnr_(0.0),
        nframes_(0) {}

  ~SharpnessTest() override {}

  void SetUp() override {
    InitializeConfig(encoding_mode_);
    if (encoding_mode_ == ::libaom_test::kTwoPassGood) {
      cfg_.rc_target_bitrate = kBitrate;
      cfg_.g_lag_in_frames = 5;
    }
  }

  void BeginPassHook(unsigned int) override {
    psnr_ = 0.0;
    nframes_ = 0;
  }

  void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) override {
    psnr_ += pkt->data.psnr.psnr[0];
    nframes_++;
  }

  void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                          ::libaom_test::Encoder *encoder) override {
    if (video->frame() == 0) {
      encoder->Control(AOME_SET_CPUUSED, cpu_used_);
      encoder->Control(AOME_SET_SHARPNESS, sharpness_level_);
      if (encoding_mode_ == ::libaom_test::kTwoPassGood) {
        encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
        encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7);
        encoder->Control(AOME_SET_ARNR_STRENGTH, 5);
      } else if (encoding_mode_ == ::libaom_test::kAllIntra) {
        encoder->Control(AOME_SET_CQ_LEVEL, kCqLevel);
      }
    }
  }

  double GetAveragePsnr() const {
    if (nframes_) return psnr_ / nframes_;
    return 0.0;
  }

  double GetPsnrThreshold() {
    return kPsnrThreshold.at(encoding_mode_).at(cpu_used_).at(sharpness_level_);
  }

  void DoTest() {
    init_flags_ = AOM_CODEC_USE_PSNR;

    std::unique_ptr<libaom_test::VideoSource> video(
        new libaom_test::Y4mVideoSource("paris_352_288_30.y4m", 0, kFrames));
    ASSERT_NE(video, nullptr);

    ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
    const double psnr = GetAveragePsnr();
    EXPECT_GT(psnr, GetPsnrThreshold())
        << "encoding mode = " << encoding_mode_ << ", cpu used = " << cpu_used_
        << ", sharpness level = " << sharpness_level_;
  }

 private:
  const libaom_test::TestMode encoding_mode_;
  const int cpu_used_;
  const int sharpness_level_;
  double psnr_;
  unsigned int nframes_;
};

class SharpnessTestLarge : public SharpnessTest {};

class SharpnessAllIntraTest : public SharpnessTest {};

class SharpnessAllIntraTestLarge : public SharpnessTest {};

TEST_P(SharpnessTestLarge, SharpnessPSNRTest) { DoTest(); }

TEST_P(SharpnessAllIntraTest, SharpnessPSNRTest) { DoTest(); }

TEST_P(SharpnessAllIntraTestLarge, SharpnessPSNRTest) { DoTest(); }

AV1_INSTANTIATE_TEST_SUITE(SharpnessTestLarge,
                           ::testing::Values(::libaom_test::kTwoPassGood),
                           ::testing::Values(2, 4, 6),  // cpu_used
                           ::testing::Values(2, 5));    // sharpness level

AV1_INSTANTIATE_TEST_SUITE(SharpnessAllIntraTest,
                           ::testing::Values(::libaom_test::kAllIntra),
                           ::testing::Values(6),   // cpu_used
                           ::testing::Values(4));  // sharpness level

AV1_INSTANTIATE_TEST_SUITE(SharpnessAllIntraTestLarge,
                           ::testing::Values(::libaom_test::kAllIntra),
                           ::testing::Values(3, 6, 9),  // cpu_used
                           ::testing::Values(2, 5));    // sharpness level
}  // namespace
