/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "./vpx_config.h"
#include "./vp8_rtcd.h"

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

#include "test/buffer.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "vpx/vpx_integer.h"

typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr,
                         int pred_stride, unsigned char *dst_ptr,
                         int dst_stride);
namespace {

using libvpx_test::Buffer;

class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
 protected:
  virtual void SetUp() {
    UUT = GetParam();

    input = new Buffer<int16_t>(4, 4, 0);
    ASSERT_NE(input, nullptr);
    ASSERT_TRUE(input->Init());
    predict = new Buffer<uint8_t>(4, 4, 3);
    ASSERT_NE(predict, nullptr);
    ASSERT_TRUE(predict->Init());
    output = new Buffer<uint8_t>(4, 4, 3);
    ASSERT_NE(output, nullptr);
    ASSERT_TRUE(output->Init());
  }

  virtual void TearDown() {
    delete input;
    delete predict;
    delete output;
    libvpx_test::ClearSystemState();
  }

  IdctFunc UUT;
  Buffer<int16_t> *input;
  Buffer<uint8_t> *predict;
  Buffer<uint8_t> *output;
};

TEST_P(IDCTTest, TestAllZeros) {
  // When the input is '0' the output will be '0'.
  input->Set(0);
  predict->Set(0);
  output->Set(0);

  ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
                               predict->stride(), output->TopLeftPixel(),
                               output->stride()));

  ASSERT_TRUE(input->CheckValues(0));
  ASSERT_TRUE(input->CheckPadding());
  ASSERT_TRUE(output->CheckValues(0));
  ASSERT_TRUE(output->CheckPadding());
}

TEST_P(IDCTTest, TestAllOnes) {
  input->Set(0);
  ASSERT_NE(input->TopLeftPixel(), nullptr);
  // When the first element is '4' it will fill the output buffer with '1'.
  input->TopLeftPixel()[0] = 4;
  predict->Set(0);
  output->Set(0);

  ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
                               predict->stride(), output->TopLeftPixel(),
                               output->stride()));

  ASSERT_TRUE(output->CheckValues(1));
  ASSERT_TRUE(output->CheckPadding());
}

TEST_P(IDCTTest, TestAddOne) {
  // Set the transform output to '1' and make sure it gets added to the
  // prediction buffer.
  input->Set(0);
  ASSERT_NE(input->TopLeftPixel(), nullptr);
  input->TopLeftPixel()[0] = 4;
  output->Set(0);

  uint8_t *pred = predict->TopLeftPixel();
  for (int y = 0; y < 4; ++y) {
    for (int x = 0; x < 4; ++x) {
      pred[y * predict->stride() + x] = y * 4 + x;
    }
  }

  ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
                               predict->stride(), output->TopLeftPixel(),
                               output->stride()));

  uint8_t const *out = output->TopLeftPixel();
  for (int y = 0; y < 4; ++y) {
    for (int x = 0; x < 4; ++x) {
      EXPECT_EQ(1 + y * 4 + x, out[y * output->stride() + x]);
    }
  }

  if (HasFailure()) {
    output->DumpBuffer();
  }

  ASSERT_TRUE(output->CheckPadding());
}

TEST_P(IDCTTest, TestWithData) {
  // Test a single known input.
  predict->Set(0);

  int16_t *in = input->TopLeftPixel();
  for (int y = 0; y < 4; ++y) {
    for (int x = 0; x < 4; ++x) {
      in[y * input->stride() + x] = y * 4 + x;
    }
  }

  ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
                               predict->stride(), output->TopLeftPixel(),
                               output->stride()));

  uint8_t *out = output->TopLeftPixel();
  for (int y = 0; y < 4; ++y) {
    for (int x = 0; x < 4; ++x) {
      switch (y * 4 + x) {
        case 0: EXPECT_EQ(11, out[y * output->stride() + x]); break;
        case 2:
        case 5:
        case 8: EXPECT_EQ(3, out[y * output->stride() + x]); break;
        case 10: EXPECT_EQ(1, out[y * output->stride() + x]); break;
        default: EXPECT_EQ(0, out[y * output->stride() + x]);
      }
    }
  }

  if (HasFailure()) {
    output->DumpBuffer();
  }

  ASSERT_TRUE(output->CheckPadding());
}

INSTANTIATE_TEST_SUITE_P(C, IDCTTest,
                         ::testing::Values(vp8_short_idct4x4llm_c));

#if HAVE_NEON
INSTANTIATE_TEST_SUITE_P(NEON, IDCTTest,
                         ::testing::Values(vp8_short_idct4x4llm_neon));
#endif  // HAVE_NEON

#if HAVE_MMX
INSTANTIATE_TEST_SUITE_P(MMX, IDCTTest,
                         ::testing::Values(vp8_short_idct4x4llm_mmx));
#endif  // HAVE_MMX

#if HAVE_MSA
INSTANTIATE_TEST_SUITE_P(MSA, IDCTTest,
                         ::testing::Values(vp8_short_idct4x4llm_msa));
#endif  // HAVE_MSA

#if HAVE_MMI
INSTANTIATE_TEST_SUITE_P(MMI, IDCTTest,
                         ::testing::Values(vp8_short_idct4x4llm_mmi));
#endif  // HAVE_MMI
}  // namespace
