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

#include "config/av1_rtcd.h"

#include "aom_mem/aom_mem.h"
#include "aom_ports/aom_timer.h"
#include "aom_ports/mem.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/util.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"

namespace {
typedef int64_t (*frame_error_func)(const uint8_t *const ref, int stride,
                                    const uint8_t *const dst, int p_width,
                                    int p_height, int p_stride);
#if HAVE_AVX2 || HAVE_SSE2
const int kBlockWidth[] = {
  832, 834, 640, 1280, 1920,
};
const int kBlockHeight[] = {
  480, 482, 360, 720, 1080,
};
#endif
typedef std::tuple<frame_error_func, int, int> FrameErrorParam;

class AV1FrameErrorTest : public ::testing::TestWithParam<FrameErrorParam> {
 public:
  virtual ~AV1FrameErrorTest() {}
  virtual void SetUp() {
    rnd_.Reset(libaom_test::ACMRandom::DeterministicSeed());
  }
  virtual void TearDown() { libaom_test::ClearSystemState(); }

 protected:
  void RandomValues(frame_error_func test_impl, int width, int height);
  void ExtremeValues(frame_error_func test_impl, int width, int height);
  void RunSpeedTest(frame_error_func test_impl, int width, int height);
  libaom_test::ACMRandom rnd_;
};
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AV1FrameErrorTest);

void AV1FrameErrorTest::RandomValues(frame_error_func test_impl, int width,
                                     int height) {
  const int stride = (((width * 3) / 2) + 15) & ~15;
  const int max_blk_size = stride * height;
  uint8_t *const dst =
      static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*dst)));
  uint8_t *const ref =
      static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*ref)));
  ASSERT_TRUE(dst != NULL);
  ASSERT_TRUE(ref != NULL);
  for (int i = 0; i < max_blk_size; ++i) {
    dst[i] = rnd_.Rand8();
    ref[i] = rnd_.Rand8();
  }
  const int64_t ref_error =
      av1_calc_frame_error_c(ref, stride, dst, width, height, stride);
  const int64_t test_error = test_impl(ref, stride, dst, width, height, stride);
  ASSERT_EQ(test_error, ref_error) << width << "x" << height;
  aom_free(dst);
  aom_free(ref);
}

void AV1FrameErrorTest::ExtremeValues(frame_error_func test_impl, int width,
                                      int height) {
  const int stride = (((width * 3) / 2) + 15) & ~15;
  const int max_blk_size = stride * height;
  uint8_t *const dst =
      static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*dst)));
  uint8_t *const ref =
      static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*ref)));
  ASSERT_TRUE(dst != NULL);
  ASSERT_TRUE(ref != NULL);
  for (int r = 0; r < 2; r++) {
    if (r == 0) {
      memset(dst, 0, max_blk_size);
      memset(ref, 255, max_blk_size);
    } else if (r == 1) {
      memset(dst, 255, max_blk_size);
      memset(ref, 0, max_blk_size);
    }
    const int64_t ref_error =
        av1_calc_frame_error_c(ref, stride, dst, width, height, stride);
    const int64_t test_error =
        test_impl(ref, stride, dst, width, height, stride);
    ASSERT_EQ(test_error, ref_error) << width << "x" << height;
  }
  aom_free(dst);
  aom_free(ref);
}

void AV1FrameErrorTest::RunSpeedTest(frame_error_func test_impl, int width,
                                     int height) {
  const int stride = (((width * 3) / 2) + 15) & ~15;
  const int max_blk_size = stride * height;
  uint8_t *const dst =
      static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*dst)));
  uint8_t *const ref =
      static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*ref)));
  ASSERT_TRUE(dst != NULL);
  ASSERT_TRUE(ref != NULL);
  for (int i = 0; i < max_blk_size; ++i) {
    dst[i] = ref[i] = rnd_.Rand8();
  }
  const int num_loops = 10000000 / (width + height);
  frame_error_func funcs[2] = { av1_calc_frame_error_c, test_impl };
  double elapsed_time[2] = { 0 };
  for (int i = 0; i < 2; ++i) {
    aom_usec_timer timer;
    aom_usec_timer_start(&timer);
    frame_error_func func = funcs[i];
    for (int j = 0; j < num_loops; ++j) {
      func(ref, stride, dst, width, height, stride);
    }
    aom_usec_timer_mark(&timer);
    double time = static_cast<double>(aom_usec_timer_elapsed(&timer));
    elapsed_time[i] = 1000.0 * time / num_loops;
  }
  aom_free(dst);
  aom_free(ref);
  printf("av1_calc_frame_error %3dx%-3d: %7.2f/%7.2fns", width, height,
         elapsed_time[0], elapsed_time[1]);
  printf("(%3.2f)\n", elapsed_time[0] / elapsed_time[1]);
}

TEST_P(AV1FrameErrorTest, CheckOutput) {
  RandomValues(GET_PARAM(0), GET_PARAM(1), GET_PARAM(2));
  ExtremeValues(GET_PARAM(0), GET_PARAM(1), GET_PARAM(2));
}

TEST_P(AV1FrameErrorTest, DISABLED_Speed) {
  RunSpeedTest(GET_PARAM(0), GET_PARAM(1), GET_PARAM(2));
}

#if HAVE_SSE2
INSTANTIATE_TEST_SUITE_P(
    SSE2, AV1FrameErrorTest,
    ::testing::Combine(::testing::Values(&av1_calc_frame_error_sse2),
                       ::testing::ValuesIn(kBlockWidth),
                       ::testing::ValuesIn(kBlockHeight)));
#endif

#if HAVE_AVX2
INSTANTIATE_TEST_SUITE_P(
    AVX2, AV1FrameErrorTest,
    ::testing::Combine(::testing::Values(&av1_calc_frame_error_avx2),
                       ::testing::ValuesIn(kBlockWidth),
                       ::testing::ValuesIn(kBlockHeight)));
#endif
}  // namespace
