/*
 * 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 "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
const int kBlockWidth[] = {
  832, 834, 640, 1280, 1920,
};
const int kBlockHeight[] = {
  480, 482, 360, 720, 1080,
};
#endif
typedef ::testing::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_;
};

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 *dst, *ref;
  dst = (uint8_t *)aom_memalign(16, max_blk_size * sizeof(*dst));
  ref = (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 *dst, *ref;
  dst = (uint8_t *)aom_memalign(16, max_blk_size * sizeof(*dst));
  ref = (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 *dst, *ref;
  dst = (uint8_t *)aom_memalign(16, max_blk_size * sizeof(*dst));
  ref = (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_AVX2
INSTANTIATE_TEST_CASE_P(
    AVX2, AV1FrameErrorTest,
    ::testing::Combine(::testing::Values(&av1_calc_frame_error_avx2),
                       ::testing::ValuesIn(kBlockWidth),
                       ::testing::ValuesIn(kBlockHeight)));
#endif
};  // namespace
