/*
 * 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 "third_party/googletest/src/googletest/include/gtest/gtest.h"

#include "./aom_config.h"
#include "./av1_rtcd.h"
#include "aom_ports/aom_timer.h"
#include "aom_ports/mem.h"
#include "av1/common/onyxc_int.h"
#include "av1/common/txb_common.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"

namespace {
using libaom_test::ACMRandom;

typedef void (*GetLevelCountsFunc)(const uint8_t *const levels, const int width,
                                   const int height,
                                   uint8_t *const level_counts);

class TxbTest : public ::testing::TestWithParam<GetLevelCountsFunc> {
 public:
  TxbTest() : get_br_level_counts_func_(GetParam()) {}

  virtual ~TxbTest() {}

  virtual void SetUp() {
    level_counts_ref_ = reinterpret_cast<uint8_t *>(
        aom_memalign(16, sizeof(*level_counts_ref_) * MAX_TX_SQUARE));
    ASSERT_TRUE(level_counts_ref_ != NULL);
    level_counts_ = reinterpret_cast<uint8_t *>(
        aom_memalign(16, sizeof(*level_counts_) * MAX_TX_SQUARE));
    ASSERT_TRUE(level_counts_ != NULL);
  }

  virtual void TearDown() {
    aom_free(level_counts_ref_);
    aom_free(level_counts_);
    libaom_test::ClearSystemState();
  }

  void GetLevelCountsRun() {
    const int kNumTests = 10000;
    int result = 0;

    for (int tx_size = TX_4X4; tx_size < TX_SIZES_ALL; ++tx_size) {
      const int width = tx_size_wide[tx_size];
      const int height = tx_size_high[tx_size];
      levels_ = set_levels(levels_buf_, width);
      memset(levels_buf_, 0, sizeof(*levels_buf_) * MAX_TX_SQUARE);

      for (int i = 0; i < kNumTests && !result; ++i) {
        InitLevels(width, height);

        av1_get_br_level_counts_c(levels_, width, height, level_counts_ref_);
        get_br_level_counts_func_(levels_, width, height, level_counts_);

        PrintDiff(width, height);

        result = memcmp(level_counts_, level_counts_ref_,
                        sizeof(*level_counts_ref_) * MAX_TX_SQUARE);

        EXPECT_EQ(result, 0) << " width " << width << " height " << height;
      }
    }
  }

  void SpeedTestGetLevelCountsRun() {
    const int kNumTests = 10000000;
    aom_usec_timer timer;

    for (int tx_size = TX_4X4; tx_size < TX_SIZES_ALL; ++tx_size) {
      const int width = tx_size_wide[tx_size];
      const int height = tx_size_high[tx_size];
      levels_ = set_levels(levels_buf_, width);
      memset(levels_buf_, 0, sizeof(*levels_buf_) * MAX_TX_SQUARE);
      InitLevels(width, height);

      aom_usec_timer_start(&timer);
      for (int i = 0; i < kNumTests; ++i) {
        get_br_level_counts_func_(levels_, width, height, level_counts_);
      }
      aom_usec_timer_mark(&timer);

      const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
      printf("get_br_level_counts_%2dx%2d: %7.1f ms\n", width, height,
             elapsed_time / 1000.0);
    }
  }

  void InitLevels(const int width, const int height) {
    const int stride = width + TX_PAD_HOR;

    for (int i = 0; i < height; ++i) {
      for (int j = 0; j < width; ++j) {
        levels_[i * stride + j] = rnd_.Rand8() % (NUM_BASE_LEVELS + 2);
      }
    }
    for (int i = 0; i < MAX_TX_SQUARE; ++i) {
      level_counts_ref_[i] = level_counts_[i] = 255;
    }
  }

  void PrintDiff(const int width, const int height) const {
    if (memcmp(level_counts_, level_counts_ref_,
               sizeof(*level_counts_ref_) * MAX_TX_SQUARE)) {
      for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
          if (level_counts_ref_[y * width + x] !=
              level_counts_[y * width + x]) {
            printf("count[%d][%d] diff:%6d (ref),%6d (opt)\n", y, x,
                   level_counts_ref_[y * width + x],
                   level_counts_[y * width + x]);
            break;
          }
        }
      }
    }
  }

  GetLevelCountsFunc get_br_level_counts_func_;
  ACMRandom rnd_;
  tran_low_t *coeff_;
  uint8_t levels_buf_[TX_PAD_2D];
  uint8_t *levels_;
  uint8_t *level_counts_ref_;
  uint8_t *level_counts_;
};

TEST_P(TxbTest, BitExact) { GetLevelCountsRun(); }

TEST_P(TxbTest, DISABLED_Speed) { SpeedTestGetLevelCountsRun(); }

#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, TxbTest,
                        ::testing::Values(av1_get_br_level_counts_sse2));
#endif
}  // namespace
