// Copyright 2020 Google LLC
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.

#pragma once

#include <gtest/gtest.h>

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdlib>
#include <functional>
#include <random>
#include <vector>

#include <xnnpack.h>
#include <xnnpack/params.h>


class FillMicrokernelTester {
 public:
  inline FillMicrokernelTester& rows(size_t rows) {
    assert(rows != 0);
    this->rows_ = rows;
    return *this;
  }

  inline size_t rows() const {
    return this->rows_;
  }

  inline FillMicrokernelTester& channels(size_t channels) {
    assert(channels != 0);
    this->channels_ = channels;
    return *this;
  }

  inline size_t channels() const {
    return this->channels_;
  }

  inline FillMicrokernelTester& output_stride(size_t output_stride) {
    assert(output_stride != 0);
    this->output_stride_ = output_stride;
    return *this;
  }

  inline size_t output_stride() const {
    if (this->output_stride_ == 0) {
      return channels();
    } else {
      return this->output_stride_;
    }
  }

  inline FillMicrokernelTester& iterations(size_t iterations) {
    this->iterations_ = iterations;
    return *this;
  }

  inline size_t iterations() const {
    return this->iterations_;
  }

  void Test(xnn_x32_fill_ukernel_function fill) const {
    ASSERT_GE(output_stride(), channels());

    std::random_device random_device;
    auto rng = std::mt19937(random_device());
    auto u32rng = std::bind(std::uniform_int_distribution<uint32_t>(), rng);

    std::vector<uint32_t> output((rows() - 1) * output_stride() + channels());
    std::vector<uint32_t> output_copy(output.size());
    for (size_t iteration = 0; iteration < iterations(); iteration++) {
      std::generate(output.begin(), output.end(), std::ref(u32rng));
      std::copy(output.cbegin(), output.cend(), output_copy.begin());
      const uint32_t fill_value = u32rng();

      // Call optimized micro-kernel.
      fill(
        rows(),
        channels() * sizeof(uint32_t),
        output.data(),
        output_stride() * sizeof(uint32_t),
        &fill_value);

      // Verify results.
      for (size_t i = 0; i < rows(); i++) {
        for (size_t c = 0; c < channels(); c++) {
          ASSERT_EQ(output[i * output_stride() + c], fill_value)
            << "at row " << i << " / " << rows()
            << ", channel " << c << " / " << channels()
            << ", fill value 0x" << std::hex << std::setw(8) << std::setfill('0') << fill_value
            << ", output value 0x" << std::hex << std::setw(8) << std::setfill('0') << output[i * output_stride() + c];
        }
      }
      for (size_t i = 0; i + 1 < rows(); i++) {
        for (size_t c = channels(); c < output_stride(); c++) {
          ASSERT_EQ(output[i * output_stride() + c], output_copy[i * output_stride() + c])
            << "at row " << i << " / " << rows()
            << ", channel " << c << " / " << channels()
            << ", original value 0x" << std::hex << std::setw(8) << std::setfill('0')
            << output_copy[i * output_stride() + c]
            << ", output value 0x" << std::hex << std::setw(8) << std::setfill('0') << output[i * output_stride() + c];
        }
      }
    }
  }

 private:
  size_t rows_{1};
  size_t channels_{1};
  size_t output_stride_{0};
  size_t iterations_{15};
};
