/*
 * 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 <cstdlib>
#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 "common/args_helper.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;

    EXPECT_EQ(AOM_CODEC_OK,
              aom_codec_enc_config_default(iface_cx, &enc_cfg, 0));
    EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc_, iface_cx, &enc_cfg, 0));
#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, 0 };

    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
