/*
 * 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("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
