/*
 *  Copyright (c) 2012 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 <limits.h>
#include <stdio.h>
#include <string.h>
#include <tuple>

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

#include "./vpx_config.h"
#if CONFIG_VP9_ENCODER
#include "./vp9_rtcd.h"
#endif

#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "vpx_dsp/ssim.h"
#include "vpx_mem/vpx_mem.h"

extern "C" double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch,
                                       uint8_t *img2, int img2_pitch, int width,
                                       int height, Ssimv *sv2, Metrics *m,
                                       int do_inconsistency);

using libvpx_test::ACMRandom;

namespace {
class ConsistencyTestBase : public ::testing::Test {
 public:
  ConsistencyTestBase(int width, int height) : width_(width), height_(height) {}

  static void SetUpTestCase() {
    source_data_[0] = reinterpret_cast<uint8_t *>(
        vpx_memalign(kDataAlignment, kDataBufferSize));
    reference_data_[0] = reinterpret_cast<uint8_t *>(
        vpx_memalign(kDataAlignment, kDataBufferSize));
    source_data_[1] = reinterpret_cast<uint8_t *>(
        vpx_memalign(kDataAlignment, kDataBufferSize));
    reference_data_[1] = reinterpret_cast<uint8_t *>(
        vpx_memalign(kDataAlignment, kDataBufferSize));
    ssim_array_ = new Ssimv[kDataBufferSize / 16];
  }

  static void ClearSsim() { memset(ssim_array_, 0, kDataBufferSize / 16); }
  static void TearDownTestCase() {
    vpx_free(source_data_[0]);
    source_data_[0] = NULL;
    vpx_free(reference_data_[0]);
    reference_data_[0] = NULL;
    vpx_free(source_data_[1]);
    source_data_[1] = NULL;
    vpx_free(reference_data_[1]);
    reference_data_[1] = NULL;

    delete[] ssim_array_;
  }

  virtual void TearDown() { libvpx_test::ClearSystemState(); }

 protected:
  // Handle frames up to 640x480
  static const int kDataAlignment = 16;
  static const int kDataBufferSize = 640 * 480;

  virtual void SetUp() {
    source_stride_ = (width_ + 31) & ~31;
    reference_stride_ = width_ * 2;
    rnd_.Reset(ACMRandom::DeterministicSeed());
  }

  void FillRandom(uint8_t *data, int stride, int width, int height) {
    for (int h = 0; h < height; ++h) {
      for (int w = 0; w < width; ++w) {
        data[h * stride + w] = rnd_.Rand8();
      }
    }
  }

  void FillRandom(uint8_t *data, int stride) {
    FillRandom(data, stride, width_, height_);
  }

  void Copy(uint8_t *reference, uint8_t *source) {
    memcpy(reference, source, kDataBufferSize);
  }

  void Blur(uint8_t *data, int stride, int taps) {
    int sum = 0;
    int half_taps = taps / 2;
    for (int h = 0; h < height_; ++h) {
      for (int w = 0; w < taps; ++w) {
        sum += data[w + h * stride];
      }
      for (int w = taps; w < width_; ++w) {
        sum += data[w + h * stride] - data[w - taps + h * stride];
        data[w - half_taps + h * stride] = (sum + half_taps) / taps;
      }
    }
    for (int w = 0; w < width_; ++w) {
      for (int h = 0; h < taps; ++h) {
        sum += data[h + w * stride];
      }
      for (int h = taps; h < height_; ++h) {
        sum += data[w + h * stride] - data[(h - taps) * stride + w];
        data[(h - half_taps) * stride + w] = (sum + half_taps) / taps;
      }
    }
  }
  int width_, height_;
  static uint8_t *source_data_[2];
  int source_stride_;
  static uint8_t *reference_data_[2];
  int reference_stride_;
  static Ssimv *ssim_array_;
  Metrics metrics_;

  ACMRandom rnd_;
};

#if CONFIG_VP9_ENCODER
typedef std::tuple<int, int> ConsistencyParam;
class ConsistencyVP9Test
    : public ConsistencyTestBase,
      public ::testing::WithParamInterface<ConsistencyParam> {
 public:
  ConsistencyVP9Test() : ConsistencyTestBase(GET_PARAM(0), GET_PARAM(1)) {}

 protected:
  double CheckConsistency(int frame) {
    EXPECT_LT(frame, 2) << "Frame to check has to be less than 2.";
    return vpx_get_ssim_metrics(source_data_[frame], source_stride_,
                                reference_data_[frame], reference_stride_,
                                width_, height_, ssim_array_, &metrics_, 1);
  }
};
#endif  // CONFIG_VP9_ENCODER

uint8_t *ConsistencyTestBase::source_data_[2] = { NULL, NULL };
uint8_t *ConsistencyTestBase::reference_data_[2] = { NULL, NULL };
Ssimv *ConsistencyTestBase::ssim_array_ = NULL;

#if CONFIG_VP9_ENCODER
TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
  FillRandom(source_data_[0], source_stride_);
  Copy(source_data_[1], source_data_[0]);
  Copy(reference_data_[0], source_data_[0]);
  Blur(reference_data_[0], reference_stride_, 3);
  Copy(reference_data_[1], source_data_[0]);
  Blur(reference_data_[1], reference_stride_, 3);

  double inconsistency = CheckConsistency(1);
  inconsistency = CheckConsistency(0);
  EXPECT_EQ(inconsistency, 0.0)
      << "Should have 0 inconsistency if they are exactly the same.";

  // If sources are not consistent reference frames inconsistency should
  // be less than if the source is consistent.
  FillRandom(source_data_[0], source_stride_);
  FillRandom(source_data_[1], source_stride_);
  FillRandom(reference_data_[0], reference_stride_);
  FillRandom(reference_data_[1], reference_stride_);
  CheckConsistency(0);
  inconsistency = CheckConsistency(1);

  Copy(source_data_[1], source_data_[0]);
  CheckConsistency(0);
  double inconsistency2 = CheckConsistency(1);
  EXPECT_LT(inconsistency, inconsistency2)
      << "Should have less inconsistency if source itself is inconsistent.";

  // Less of a blur should be less inconsistent than more blur coming off a
  // a frame with no blur.
  ClearSsim();
  FillRandom(source_data_[0], source_stride_);
  Copy(source_data_[1], source_data_[0]);
  Copy(reference_data_[0], source_data_[0]);
  Copy(reference_data_[1], source_data_[0]);
  Blur(reference_data_[1], reference_stride_, 4);
  CheckConsistency(0);
  inconsistency = CheckConsistency(1);
  ClearSsim();
  Copy(reference_data_[1], source_data_[0]);
  Blur(reference_data_[1], reference_stride_, 8);
  CheckConsistency(0);
  inconsistency2 = CheckConsistency(1);

  EXPECT_LT(inconsistency, inconsistency2)
      << "Stronger Blur should produce more inconsistency.";
}
#endif  // CONFIG_VP9_ENCODER

using std::make_tuple;

//------------------------------------------------------------------------------
// C functions

#if CONFIG_VP9_ENCODER
const ConsistencyParam c_vp9_tests[] = {
  make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238)
};
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
                        ::testing::ValuesIn(c_vp9_tests));
#endif

}  // namespace
