/*
 *  Copyright (c) 2016 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.
 */

#ifndef VPX_TEST_BUFFER_H_
#define VPX_TEST_BUFFER_H_

#include <stdio.h>

#include <limits>

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

#include "test/acm_random.h"
#include "vpx/vpx_integer.h"
#include "vpx_mem/vpx_mem.h"

namespace libvpx_test {

template <typename T>
class Buffer {
 public:
  Buffer(int width, int height, int top_padding, int left_padding,
         int right_padding, int bottom_padding)
      : width_(width), height_(height), top_padding_(top_padding),
        left_padding_(left_padding), right_padding_(right_padding),
        bottom_padding_(bottom_padding), alignment_(0), padding_value_(0),
        stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}

  Buffer(int width, int height, int top_padding, int left_padding,
         int right_padding, int bottom_padding, unsigned int alignment)
      : width_(width), height_(height), top_padding_(top_padding),
        left_padding_(left_padding), right_padding_(right_padding),
        bottom_padding_(bottom_padding), alignment_(alignment),
        padding_value_(0), stride_(0), raw_size_(0), num_elements_(0),
        raw_buffer_(NULL) {}

  Buffer(int width, int height, int padding)
      : width_(width), height_(height), top_padding_(padding),
        left_padding_(padding), right_padding_(padding),
        bottom_padding_(padding), alignment_(0), padding_value_(0), stride_(0),
        raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}

  Buffer(int width, int height, int padding, unsigned int alignment)
      : width_(width), height_(height), top_padding_(padding),
        left_padding_(padding), right_padding_(padding),
        bottom_padding_(padding), alignment_(alignment), padding_value_(0),
        stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}

  ~Buffer() {
    if (alignment_) {
      vpx_free(raw_buffer_);
    } else {
      delete[] raw_buffer_;
    }
  }

  T *TopLeftPixel() const;

  int stride() const { return stride_; }

  // Set the buffer (excluding padding) to 'value'.
  void Set(const T value);

  // Set the buffer (excluding padding) to the output of ACMRandom function
  // 'rand_func'.
  void Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)());

  // Set the buffer (excluding padding) to the output of ACMRandom function
  // 'RandRange' with range 'low' to 'high' which typically must be within
  // testing::internal::Random::kMaxRange (1u << 31). However, because we want
  // to allow negative low (and high) values, it is restricted to INT32_MAX
  // here.
  void Set(ACMRandom *rand_class, const T low, const T high);

  // Copy the contents of Buffer 'a' (excluding padding).
  void CopyFrom(const Buffer<T> &a);

  void DumpBuffer() const;

  // Highlight the differences between two buffers if they are the same size.
  void PrintDifference(const Buffer<T> &a) const;

  bool HasPadding() const;

  // Sets all the values in the buffer to 'padding_value'.
  void SetPadding(const T padding_value);

  // Checks if all the values (excluding padding) are equal to 'value' if the
  // Buffers are the same size.
  bool CheckValues(const T value) const;

  // Check that padding matches the expected value or there is no padding.
  bool CheckPadding() const;

  // Compare the non-padding portion of two buffers if they are the same size.
  bool CheckValues(const Buffer<T> &a) const;

  bool Init() {
    if (raw_buffer_ != NULL) return false;
    EXPECT_GT(width_, 0);
    EXPECT_GT(height_, 0);
    EXPECT_GE(top_padding_, 0);
    EXPECT_GE(left_padding_, 0);
    EXPECT_GE(right_padding_, 0);
    EXPECT_GE(bottom_padding_, 0);
    stride_ = left_padding_ + width_ + right_padding_;
    num_elements_ = stride_ * (top_padding_ + height_ + bottom_padding_);
    raw_size_ = num_elements_ * sizeof(T);
    if (alignment_) {
      EXPECT_GE(alignment_, sizeof(T));
      // Ensure alignment of the first value will be preserved.
      EXPECT_EQ((left_padding_ * sizeof(T)) % alignment_, 0u);
      // Ensure alignment of the subsequent rows will be preserved when there is
      // a stride.
      if (stride_ != width_) {
        EXPECT_EQ((stride_ * sizeof(T)) % alignment_, 0u);
      }
      raw_buffer_ = reinterpret_cast<T *>(vpx_memalign(alignment_, raw_size_));
    } else {
      raw_buffer_ = new (std::nothrow) T[num_elements_];
    }
    EXPECT_TRUE(raw_buffer_ != NULL);
    SetPadding(std::numeric_limits<T>::max());
    return !::testing::Test::HasFailure();
  }

 private:
  bool BufferSizesMatch(const Buffer<T> &a) const;

  const int width_;
  const int height_;
  const int top_padding_;
  const int left_padding_;
  const int right_padding_;
  const int bottom_padding_;
  const unsigned int alignment_;
  T padding_value_;
  int stride_;
  int raw_size_;
  int num_elements_;
  T *raw_buffer_;
};

template <typename T>
T *Buffer<T>::TopLeftPixel() const {
  if (!raw_buffer_) return NULL;
  return raw_buffer_ + (top_padding_ * stride_) + left_padding_;
}

template <typename T>
void Buffer<T>::Set(const T value) {
  if (!raw_buffer_) return;
  T *src = TopLeftPixel();
  for (int height = 0; height < height_; ++height) {
    for (int width = 0; width < width_; ++width) {
      src[width] = value;
    }
    src += stride_;
  }
}

template <typename T>
void Buffer<T>::Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)()) {
  if (!raw_buffer_) return;
  T *src = TopLeftPixel();
  for (int height = 0; height < height_; ++height) {
    for (int width = 0; width < width_; ++width) {
      src[width] = (*rand_class.*rand_func)();
    }
    src += stride_;
  }
}

template <typename T>
void Buffer<T>::Set(ACMRandom *rand_class, const T low, const T high) {
  if (!raw_buffer_) return;

  EXPECT_LE(low, high);
  EXPECT_LE(static_cast<int64_t>(high) - low,
            std::numeric_limits<int32_t>::max());

  T *src = TopLeftPixel();
  for (int height = 0; height < height_; ++height) {
    for (int width = 0; width < width_; ++width) {
      // 'low' will be promoted to unsigned given the return type of RandRange.
      // Store the value as an int to avoid unsigned overflow warnings when
      // 'low' is negative.
      const int32_t value =
          static_cast<int32_t>((*rand_class).RandRange(high - low));
      src[width] = static_cast<T>(value + low);
    }
    src += stride_;
  }
}

template <typename T>
void Buffer<T>::CopyFrom(const Buffer<T> &a) {
  if (!raw_buffer_) return;
  if (!BufferSizesMatch(a)) return;

  T *a_src = a.TopLeftPixel();
  T *b_src = this->TopLeftPixel();
  for (int height = 0; height < height_; ++height) {
    for (int width = 0; width < width_; ++width) {
      b_src[width] = a_src[width];
    }
    a_src += a.stride();
    b_src += this->stride();
  }
}

template <typename T>
void Buffer<T>::DumpBuffer() const {
  if (!raw_buffer_) return;
  for (int height = 0; height < height_ + top_padding_ + bottom_padding_;
       ++height) {
    for (int width = 0; width < stride_; ++width) {
      printf("%4d", raw_buffer_[height + width * stride_]);
    }
    printf("\n");
  }
}

template <typename T>
bool Buffer<T>::HasPadding() const {
  if (!raw_buffer_) return false;
  return top_padding_ || left_padding_ || right_padding_ || bottom_padding_;
}

template <typename T>
void Buffer<T>::PrintDifference(const Buffer<T> &a) const {
  if (!raw_buffer_) return;
  if (!BufferSizesMatch(a)) return;

  T *a_src = a.TopLeftPixel();
  T *b_src = TopLeftPixel();

  printf("This buffer:\n");
  for (int height = 0; height < height_; ++height) {
    for (int width = 0; width < width_; ++width) {
      if (a_src[width] != b_src[width]) {
        printf("*%3d", b_src[width]);
      } else {
        printf("%4d", b_src[width]);
      }
    }
    printf("\n");
    a_src += a.stride();
    b_src += this->stride();
  }

  a_src = a.TopLeftPixel();
  b_src = TopLeftPixel();

  printf("Reference buffer:\n");
  for (int height = 0; height < height_; ++height) {
    for (int width = 0; width < width_; ++width) {
      if (a_src[width] != b_src[width]) {
        printf("*%3d", a_src[width]);
      } else {
        printf("%4d", a_src[width]);
      }
    }
    printf("\n");
    a_src += a.stride();
    b_src += this->stride();
  }
}

template <typename T>
void Buffer<T>::SetPadding(const T padding_value) {
  if (!raw_buffer_) return;
  padding_value_ = padding_value;

  T *src = raw_buffer_;
  for (int i = 0; i < num_elements_; ++i) {
    src[i] = padding_value;
  }
}

template <typename T>
bool Buffer<T>::CheckValues(const T value) const {
  if (!raw_buffer_) return false;
  T *src = TopLeftPixel();
  for (int height = 0; height < height_; ++height) {
    for (int width = 0; width < width_; ++width) {
      if (value != src[width]) {
        return false;
      }
    }
    src += stride_;
  }
  return true;
}

template <typename T>
bool Buffer<T>::CheckPadding() const {
  if (!raw_buffer_) return false;
  if (!HasPadding()) return true;

  // Top padding.
  T const *top = raw_buffer_;
  for (int i = 0; i < stride_ * top_padding_; ++i) {
    if (padding_value_ != top[i]) {
      return false;
    }
  }

  // Left padding.
  T const *left = TopLeftPixel() - left_padding_;
  for (int height = 0; height < height_; ++height) {
    for (int width = 0; width < left_padding_; ++width) {
      if (padding_value_ != left[width]) {
        return false;
      }
    }
    left += stride_;
  }

  // Right padding.
  T const *right = TopLeftPixel() + width_;
  for (int height = 0; height < height_; ++height) {
    for (int width = 0; width < right_padding_; ++width) {
      if (padding_value_ != right[width]) {
        return false;
      }
    }
    right += stride_;
  }

  // Bottom padding
  T const *bottom = raw_buffer_ + (top_padding_ + height_) * stride_;
  for (int i = 0; i < stride_ * bottom_padding_; ++i) {
    if (padding_value_ != bottom[i]) {
      return false;
    }
  }

  return true;
}

template <typename T>
bool Buffer<T>::CheckValues(const Buffer<T> &a) const {
  if (!raw_buffer_) return false;
  if (!BufferSizesMatch(a)) return false;

  T *a_src = a.TopLeftPixel();
  T *b_src = this->TopLeftPixel();
  for (int height = 0; height < height_; ++height) {
    for (int width = 0; width < width_; ++width) {
      if (a_src[width] != b_src[width]) {
        return false;
      }
    }
    a_src += a.stride();
    b_src += this->stride();
  }
  return true;
}

template <typename T>
bool Buffer<T>::BufferSizesMatch(const Buffer<T> &a) const {
  if (!raw_buffer_) return false;
  if (a.width_ != this->width_ || a.height_ != this->height_) {
    printf(
        "Reference buffer of size %dx%d does not match this buffer which is "
        "size %dx%d\n",
        a.width_, a.height_, this->width_, this->height_);
    return false;
  }

  return true;
}
}  // namespace libvpx_test
#endif  // VPX_TEST_BUFFER_H_
