/*
 * Copyright (c) 2020, 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 <math.h>
#include <stdlib.h>
#include <string.h>
#include <tuple>

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

#include "config/av1_rtcd.h"
#include "config/aom_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/register_state_check.h"
#include "test/transform_test_base.h"
#include "test/util.h"
#include "av1/common/entropy.h"
#include "aom/aom_codec.h"
#include "aom/aom_integer.h"
#include "aom_ports/mem.h"

using libaom_test::ACMRandom;

namespace {

template <typename OutputType>
using FdctFunc = void (*)(const int16_t *in, OutputType *out, int stride);

template <typename OutputType>
using FhtFunc = void (*)(const int16_t *in, OutputType *out, int stride,
                         TxfmParam *txfm_param);

template <typename OutputType>
using Fdct4x4Param =
    std::tuple<FdctFunc<OutputType>, FhtFunc<OutputType>, aom_bit_depth_t, int>;

#if HAVE_NEON || HAVE_SSE2
void fdct4x4_ref(const int16_t *in, tran_low_t *out, int stride,
                 TxfmParam * /*txfm_param*/) {
  aom_fdct4x4_c(in, out, stride);
}

void fdct4x4_lp_ref(const int16_t *in, int16_t *out, int stride,
                    TxfmParam * /*txfm_param*/) {
  aom_fdct4x4_lp_c(in, out, stride);
}
#endif

template <typename OutputType>
class Trans4x4FDCT : public libaom_test::TransformTestBase<OutputType>,
                     public ::testing::TestWithParam<Fdct4x4Param<OutputType>> {
 public:
  ~Trans4x4FDCT() override = default;

  using TxfmBaseOutType = libaom_test::TransformTestBase<OutputType>;
  void SetUp() override {
    fwd_txfm_ = std::get<0>(this->GetParam());
    TxfmBaseOutType::pitch_ = 4;
    TxfmBaseOutType::height_ = 4;
    TxfmBaseOutType::fwd_txfm_ref = std::get<1>(this->GetParam());
    TxfmBaseOutType::bit_depth_ = std::get<2>(this->GetParam());
    TxfmBaseOutType::mask_ = (1 << TxfmBaseOutType::bit_depth_) - 1;
    TxfmBaseOutType::num_coeffs_ = std::get<3>(this->GetParam());
  }

 protected:
  void RunFwdTxfm(const int16_t *in, OutputType *out, int stride) override {
    fwd_txfm_(in, out, stride);
  }

  void RunInvTxfm(const OutputType *out, uint8_t *dst, int stride) override {
    (void)out;
    (void)dst;
    (void)stride;
  }

  FdctFunc<OutputType> fwd_txfm_;
};

using Trans4x4FDCTTranLow = Trans4x4FDCT<tran_low_t>;
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Trans4x4FDCTTranLow);
TEST_P(Trans4x4FDCTTranLow, CoeffCheck) { RunCoeffCheck(); }
TEST_P(Trans4x4FDCTTranLow, MemCheck) { RunMemCheck(); }

using Trans4x4FDCTInt16 = Trans4x4FDCT<int16_t>;
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Trans4x4FDCTInt16);
TEST_P(Trans4x4FDCTInt16, CoeffCheck) { RunCoeffCheck(); }
TEST_P(Trans4x4FDCTInt16, MemCheck) { RunMemCheck(); }

using std::make_tuple;

#if HAVE_NEON
INSTANTIATE_TEST_SUITE_P(NEON, Trans4x4FDCTTranLow,
                         ::testing::Values(make_tuple(&aom_fdct4x4_neon,
                                                      &fdct4x4_ref, AOM_BITS_8,
                                                      16)));

INSTANTIATE_TEST_SUITE_P(NEON, Trans4x4FDCTInt16,
                         ::testing::Values(make_tuple(&aom_fdct4x4_lp_neon,
                                                      &fdct4x4_lp_ref,
                                                      AOM_BITS_8, 16)));
#endif

#if HAVE_SSE2
INSTANTIATE_TEST_SUITE_P(SSE2, Trans4x4FDCTTranLow,
                         ::testing::Values(make_tuple(&aom_fdct4x4_sse2,
                                                      &fdct4x4_ref, AOM_BITS_8,
                                                      16)));

INSTANTIATE_TEST_SUITE_P(SSE2, Trans4x4FDCTInt16,
                         ::testing::Values(make_tuple(&aom_fdct4x4_lp_sse2,
                                                      &fdct4x4_lp_ref,
                                                      AOM_BITS_8, 16)));
#endif
}  // namespace
