/*
 * 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 <cstring>
#include <tuple>

#include "aom/aom_codec.h"
#include "aom/aom_decoder.h"
#include "aom/aom_encoder.h"
#include "aom/aomcx.h"
#include "aom/aomdx.h"
#include "config/aom_config.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"

namespace {
typedef std::tuple<const char *, const char *> KeyValParam;

class BaseKeyValAPI : public testing::Test {
 public:
  void SetUp() override {
#if CONFIG_AV1_ENCODER
    aom_codec_iface_t *iface_cx = aom_codec_av1_cx();
    aom_codec_enc_cfg_t enc_cfg;
#if CONFIG_REALTIME_ONLY
    const int usage = 1;
#else
    const int usage = 0;
#endif
    EXPECT_EQ(AOM_CODEC_OK,
              aom_codec_enc_config_default(iface_cx, &enc_cfg, usage));
    EXPECT_EQ(AOM_CODEC_OK,
              aom_codec_enc_init(&enc_, iface_cx, &enc_cfg, usage));
#endif
#if CONFIG_AV1_DECODER
    aom_codec_iface_t *iface_dx = aom_codec_av1_dx();
    aom_codec_dec_cfg_t dec_cfg = { 0, 0, 0, !FORCE_HIGHBITDEPTH_DECODING };

    EXPECT_EQ(AOM_CODEC_OK, aom_codec_dec_init(&dec_, iface_dx, &dec_cfg, 0));
#endif
  }

  void TearDown() override {
#if CONFIG_AV1_ENCODER
    EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc_));
#endif
#if CONFIG_AV1_DECODER
    EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&dec_));
#endif
  }

 protected:
#if CONFIG_AV1_ENCODER
  aom_codec_ctx_t enc_;
#endif
#if CONFIG_AV1_DECODER
  aom_codec_ctx_t dec_;
#endif
};

// Tests on encoder options.
// Need to add ones for the decoder in the future if it is also supported in the
// key & value API.
#if CONFIG_AV1_ENCODER
class EncValidTest : public BaseKeyValAPI,
                     public testing::WithParamInterface<KeyValParam> {};
class EncInvalidTest : public BaseKeyValAPI,
                       public testing::WithParamInterface<KeyValParam> {};

TEST_P(EncValidTest, Valid) {
  const char *key = std::get<0>(GetParam());
  const char *val = std::get<1>(GetParam());
  EXPECT_EQ(AOM_CODEC_OK, aom_codec_set_option(&enc_, key, val));
}

TEST_P(EncInvalidTest, NullArg) {
  const char *key = std::get<0>(GetParam());
  const char *val = std::get<1>(GetParam());
  EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_set_option(nullptr, key, val));
  EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_set_option(&enc_, nullptr, val));
  EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_set_option(&enc_, key, nullptr));
}

TEST_P(EncInvalidTest, InvalidParam) {
  const char *key = std::get<0>(GetParam());
  const char *val = std::get<1>(GetParam());
  EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_set_option(&enc_, key, val));
  ASSERT_NE(aom_codec_error_detail(&enc_), nullptr);
  EXPECT_GT(strlen(aom_codec_error_detail(&enc_)), 0u);
}

// No test for ratio / list for now since the API does not support any of the
// parameters of these type.
// The string type typically involves reading a path/file, which brings
// potential fails.
const KeyValParam enc_valid_params[] = {
  std::make_tuple("auto-intra-tools-off", "1"),  // uint
  std::make_tuple("min-gf-interval", "10"),      // uint
  std::make_tuple("min-partition-size", "4"),    // int
  std::make_tuple("tune", "psnr"),               // enum
};

const KeyValParam enc_invalid_params[] = {
  // no match
  std::make_tuple("a-b-c", "10"),
  // uint
  std::make_tuple("min-gf-interval", "-1"),
  std::make_tuple("min-gf-interval", "1.1"),
  std::make_tuple("min-gf-interval", "abc"),
  // int
  std::make_tuple("min-partition-size", "1.1"),
  std::make_tuple("min-partition-size", "abc"),
  // enum
  std::make_tuple("tune", "PsnR1"),
  // out of range
  std::make_tuple("cq-level", "1000"),
};

INSTANTIATE_TEST_SUITE_P(KeyValAPI, EncValidTest,
                         testing::ValuesIn(enc_valid_params));

INSTANTIATE_TEST_SUITE_P(KeyValAPI, EncInvalidTest,
                         testing::ValuesIn(enc_invalid_params));
#endif  // CONFIG_AV1_ENCODER

}  // namespace
