/*
 * Copyright (c) 2017, 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 <assert.h>

#include "./av1_rtcd.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "aom/aom_integer.h"
#include "aom_ports/aom_timer.h"

using libaom_test::ACMRandom;

namespace {
#define CONVOLVE_ROUNDING_PARAM                                            \
  const int32_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, \
      int h, int bits

typedef void (*ConvolveRoundFunc)(CONVOLVE_ROUNDING_PARAM);

typedef void (*ConvolveRoundFuncHbd)(CONVOLVE_ROUNDING_PARAM, int bd);

template <ConvolveRoundFuncHbd fn>
void highbd_convolve_rounding_8(CONVOLVE_ROUNDING_PARAM) {
  const int bd = 8;
  fn(src, src_stride, dst, dst_stride, w, h, bits, bd);
}

template <ConvolveRoundFuncHbd fn>
void highbd_convolve_rounding_10(CONVOLVE_ROUNDING_PARAM) {
  const int bd = 10;
  fn(src, src_stride, dst, dst_stride, w, h, bits, bd);
}

template <ConvolveRoundFuncHbd fn>
void highbd_convolve_rounding_12(CONVOLVE_ROUNDING_PARAM) {
  const int bd = 12;
  fn(src, src_stride, dst, dst_stride, w, h, bits, bd);
}

typedef enum { LOWBITDEPTH_TEST, HIGHBITDEPTH_TEST } DataPathType;

using std::tr1::tuple;

typedef tuple<ConvolveRoundFunc, ConvolveRoundFunc, DataPathType>
    ConvolveRoundParam;

const int kTestNum = 5000;

class ConvolveRoundTest : public ::testing::TestWithParam<ConvolveRoundParam> {
 protected:
  ConvolveRoundTest()
      : func_ref_(GET_PARAM(0)), func_(GET_PARAM(1)), data_path_(GET_PARAM(2)) {
  }
  virtual ~ConvolveRoundTest() {}

  virtual void SetUp() {
    const size_t block_size = 128 * 128;
    src_ = reinterpret_cast<int32_t *>(
        aom_memalign(16, 3 * block_size * sizeof(int32_t)));
    dst_ref_ = reinterpret_cast<uint16_t *>(src_ + block_size);
    dst_ = dst_ref_ + block_size;
  }

  virtual void TearDown() { aom_free(src_); }

  void ConvolveRoundingRun() {
    int test_num = 0;
    const int src_stride = 128;
    const int dst_stride = 128;
    int bits = 13;
    uint8_t *dst = 0;
    uint8_t *dst_ref = 0;
    int diff_wide;

    if (data_path_ == LOWBITDEPTH_TEST) {
      dst = reinterpret_cast<uint8_t *>(dst_);
      dst_ref = reinterpret_cast<uint8_t *>(dst_ref_);
#if CONFIG_HIGHBITDEPTH
    } else if (data_path_ == HIGHBITDEPTH_TEST) {
      dst = CONVERT_TO_BYTEPTR(dst_);
      dst_ref = CONVERT_TO_BYTEPTR(dst_ref_);
#endif
    } else {
      assert(0);
    }

    while (test_num < kTestNum) {
      int block_size = test_num % BLOCK_SIZES_ALL;
      int w = block_size_wide[block_size];
      int h = block_size_high[block_size];

      if (test_num % 2 == 0)
        bits -= 1;
      else
        bits += 1;

      GenerateBufferWithRandom(src_, src_stride, bits, w, h);

      func_ref_(src_, src_stride, dst_ref, dst_stride, w, h, bits);
      func_(src_, src_stride, dst, dst_stride, w, h, bits);

      diff_wide = w;
      if (data_path_ == LOWBITDEPTH_TEST) diff_wide >>= 1;
      for (int r = 0; r < h; ++r) {
        for (int c = 0; c < diff_wide; ++c) {
          ASSERT_EQ(dst_ref_[r * dst_stride + c], dst_[r * dst_stride + c])
              << "Mismatch at r: " << r << " c: " << c << " test: " << test_num;
        }
      }

      test_num++;
    }
  }

  void GenerateBufferWithRandom(int32_t *src, int src_stride, int bits, int w,
                                int h) {
    int32_t number;
    for (int r = 0; r < h; ++r) {
      for (int c = 0; c < w; ++c) {
        number = static_cast<int32_t>(rand_.Rand31());
        number %= 1 << (bits + 9);
        src[r * src_stride + c] = number;
      }
    }
  }

  ACMRandom rand_;
  int32_t *src_;
  uint16_t *dst_ref_;
  uint16_t *dst_;

  ConvolveRoundFunc func_ref_;
  ConvolveRoundFunc func_;
  DataPathType data_path_;
};

TEST_P(ConvolveRoundTest, BitExactCheck) { ConvolveRoundingRun(); }

using std::tr1::make_tuple;

#if HAVE_AVX2
const ConvolveRoundParam kConvRndParamArray[] = {
  make_tuple(&av1_convolve_rounding_c, &av1_convolve_rounding_avx2,
             LOWBITDEPTH_TEST),
  make_tuple(&highbd_convolve_rounding_8<av1_highbd_convolve_rounding_c>,
             &highbd_convolve_rounding_8<av1_highbd_convolve_rounding_avx2>,
             HIGHBITDEPTH_TEST),
  make_tuple(&highbd_convolve_rounding_10<av1_highbd_convolve_rounding_c>,
             &highbd_convolve_rounding_10<av1_highbd_convolve_rounding_avx2>,
             HIGHBITDEPTH_TEST),
  make_tuple(&highbd_convolve_rounding_12<av1_highbd_convolve_rounding_c>,
             &highbd_convolve_rounding_12<av1_highbd_convolve_rounding_avx2>,
             HIGHBITDEPTH_TEST)
};

INSTANTIATE_TEST_CASE_P(AVX2, ConvolveRoundTest,
                        ::testing::ValuesIn(kConvRndParamArray));
#endif  // HAVE_AVX2
}  // namespace
