/*
 * Copyright (c) 2018, 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 <vector>

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

#include "test/function_equivalence_test.h"
#include "test/register_state_check.h"

#include "config/aom_config.h"
#include "config/aom_dsp_rtcd.h"
#include "config/av1_rtcd.h"

#include "aom/aom_integer.h"
#include "av1/encoder/rdopt.h"

using libaom_test::FunctionEquivalenceTest;

namespace {
typedef void (*HorverFunc)(const int16_t *diff, int stride, int w, int h,
                           float *hcorr, float *vcorr);

typedef libaom_test::FuncParam<HorverFunc> TestFuncs;

typedef ::testing::tuple<const HorverFunc> HorverTestParam;

class HorverTest : public ::testing::TestWithParam<HorverTestParam> {
 public:
  virtual void SetUp() {
    data_buf_ = (int16_t *)aom_malloc(MAX_SB_SQUARE * sizeof(int16_t));
    ASSERT_NE(data_buf_, nullptr);
    target_func_ = GET_PARAM(0);
  }
  virtual void TearDown() { aom_free(data_buf_); }
  void RunHorverTest(void);
  void RunHorverTest_ExtremeValues(void);
  void RunHorverSpeedTest(int run_times);

 private:
  HorverFunc target_func_;
  ACMRandom rng_;
  int16_t *data_buf_;
};

void HorverTest::RunHorverTest(void) {
  for (int block_size = 0; block_size < BLOCK_SIZES_ALL; block_size++) {
    const int w = block_size_wide[block_size];
    const int h = block_size_high[block_size];
    for (int iter = 0; iter < 1000 && !HasFatalFailure(); ++iter) {
      float hcorr_ref = 0.0, vcorr_ref = 0.0;
      float hcorr_test = 0.0, vcorr_test = 0.0;

      for (int i = 0; i < MAX_SB_SQUARE; ++i) {
        data_buf_[i] = (rng_.Rand16() % (1 << 12)) - (1 << 11);
      }

      av1_get_horver_correlation_full_c(data_buf_, MAX_SB_SIZE, w, h,
                                        &hcorr_ref, &vcorr_ref);

      target_func_(data_buf_, MAX_SB_SIZE, w, h, &hcorr_test, &vcorr_test);

      ASSERT_LE(fabs(hcorr_ref - hcorr_test), 1e-6)
          << "hcorr incorrect (" << w << "x" << h << ")";
      ASSERT_LE(fabs(vcorr_ref - vcorr_test), 1e-6)
          << "vcorr incorrect (" << w << "x" << h << ")";
    }
    //    printf("(%3dx%-3d) passed\n", w, h);
  }
}

void HorverTest::RunHorverSpeedTest(int run_times) {
  for (int i = 0; i < MAX_SB_SQUARE; ++i) {
    data_buf_[i] = rng_.Rand16() % (1 << 12);
  }

  for (int block_size = 0; block_size < BLOCK_SIZES_ALL; block_size++) {
    const int w = block_size_wide[block_size];
    const int h = block_size_high[block_size];
    float hcorr_ref = 0.0, vcorr_ref = 0.0;
    float hcorr_test = 0.0, vcorr_test = 0.0;

    aom_usec_timer timer;
    aom_usec_timer_start(&timer);
    for (int i = 0; i < run_times; ++i) {
      av1_get_horver_correlation_full_c(data_buf_, MAX_SB_SIZE, w, h,
                                        &hcorr_ref, &vcorr_ref);
    }
    aom_usec_timer_mark(&timer);
    const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
    aom_usec_timer_start(&timer);
    for (int i = 0; i < run_times; ++i) {
      target_func_(data_buf_, MAX_SB_SIZE, w, h, &hcorr_test, &vcorr_test);
    }
    aom_usec_timer_mark(&timer);
    const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));

    printf("%3dx%-3d:%7.2f/%7.2fns (%3.2f)\n", w, h, time1, time2,
           time1 / time2);
  }
}

void HorverTest::RunHorverTest_ExtremeValues(void) {
  for (int i = 0; i < MAX_SB_SQUARE; ++i) {
    // Most of get_horver_test is squaring and summing, so simply saturating
    // the whole buffer is mostly likely to cause an overflow.
    data_buf_[i] = (1 << 12) - 1;
  }

  for (int block_size = 0; block_size < BLOCK_SIZES_ALL; block_size++) {
    const int w = block_size_wide[block_size];
    const int h = block_size_high[block_size];
    float hcorr_ref = 0.0, vcorr_ref = 0.0;
    float hcorr_test = 0.0, vcorr_test = 0.0;

    av1_get_horver_correlation_full_c(data_buf_, MAX_SB_SIZE, w, h, &hcorr_ref,
                                      &vcorr_ref);
    target_func_(data_buf_, MAX_SB_SIZE, w, h, &hcorr_test, &vcorr_test);

    ASSERT_LE(fabs(hcorr_ref - hcorr_test), 1e-6) << "hcorr incorrect";
    ASSERT_LE(fabs(vcorr_ref - vcorr_test), 1e-6) << "vcorr incorrect";
  }
}

TEST_P(HorverTest, RandomValues) { RunHorverTest(); }

TEST_P(HorverTest, ExtremeValues) { RunHorverTest_ExtremeValues(); }

TEST_P(HorverTest, DISABLED_Speed) { RunHorverSpeedTest(100000); }

#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(
    SSE4_1, HorverTest,
    ::testing::Values(av1_get_horver_correlation_full_sse4_1));
#endif  // HAVE_SSE4_1

#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(
    AVX2, HorverTest, ::testing::Values(av1_get_horver_correlation_full_avx2));
#endif  // HAVE_AVX2

}  // namespace
