// Copyright 2022 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/crc/internal/crc_memcpy.h"

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <limits>
#include <memory>
#include <string>
#include <utility>

#include "gtest/gtest.h"
#include "absl/crc/crc32c.h"
#include "absl/memory/memory.h"
#include "absl/random/distributions.h"
#include "absl/random/random.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"

namespace {

enum CrcEngine {
  X86 = 0,
  NONTEMPORAL = 1,
  FALLBACK = 2,
};

// Correctness tests:
// - Every source/destination byte alignment 0-15, every size 0-511 bytes
// - Arbitrarily aligned source, large size
template <size_t max_size>
class CrcMemcpyTest : public testing::Test {
 protected:
  CrcMemcpyTest() {
    source_ = std::make_unique<char[]>(kSize);
    destination_ = std::make_unique<char[]>(kSize);
  }
  static constexpr size_t kAlignment = 16;
  static constexpr size_t kMaxCopySize = max_size;
  static constexpr size_t kSize = kAlignment + kMaxCopySize;
  std::unique_ptr<char[]> source_;
  std::unique_ptr<char[]> destination_;

  absl::BitGen gen_;
};

// Small test is slightly larger 4096 bytes to allow coverage of the "large"
// copy function.  The minimum size to exercise all code paths in that function
// would be around 256 consecutive tests (getting every possible tail value
// and 0-2 small copy loops after the main block), so testing from 4096-4500
// will cover all of those code paths multiple times.
typedef CrcMemcpyTest<4500> CrcSmallTest;
typedef CrcMemcpyTest<(1 << 24)> CrcLargeTest;
// Parametrize the small test so that it can be done with all configurations.
template <typename ParamsT>
class x86ParamTestTemplate : public CrcSmallTest,
                             public ::testing::WithParamInterface<ParamsT> {
 protected:
  x86ParamTestTemplate() {
    if (GetParam().crc_engine_selector == FALLBACK) {
      engine_ = std::make_unique<absl::crc_internal::FallbackCrcMemcpyEngine>();
    } else if (GetParam().crc_engine_selector == NONTEMPORAL) {
      engine_ =
          std::make_unique<absl::crc_internal::CrcNonTemporalMemcpyEngine>();
    } else {
      engine_ = absl::crc_internal::CrcMemcpy::GetTestEngine(
          GetParam().vector_lanes, GetParam().integer_lanes);
    }
  }

  // Convenience method.
  ParamsT GetParam() const {
    return ::testing::WithParamInterface<ParamsT>::GetParam();
  }

  std::unique_ptr<absl::crc_internal::CrcMemcpyEngine> engine_;
};
struct TestParams {
  CrcEngine crc_engine_selector = X86;
  int vector_lanes = 0;
  int integer_lanes = 0;
};
using x86ParamTest = x86ParamTestTemplate<TestParams>;
// SmallCorrectness is designed to exercise every possible set of code paths
// in the memcpy code, not including the loop.
TEST_P(x86ParamTest, SmallCorrectnessCheckSourceAlignment) {
  constexpr size_t kTestSizes[] = {0, 100, 255, 512, 1024, 4000, kMaxCopySize};

  for (size_t source_alignment = 0; source_alignment < kAlignment;
       source_alignment++) {
    for (auto size : kTestSizes) {
      char* base_data = static_cast<char*>(source_.get()) + source_alignment;
      for (size_t i = 0; i < size; i++) {
        *(base_data + i) =
            static_cast<char>(absl::Uniform<unsigned char>(gen_));
      }
      absl::crc32c_t initial_crc =
          absl::crc32c_t{absl::Uniform<uint32_t>(gen_)};
      absl::crc32c_t experiment_crc =
          engine_->Compute(destination_.get(), source_.get() + source_alignment,
                           size, initial_crc);
      // Check the memory region to make sure it is the same
      int mem_comparison =
          memcmp(destination_.get(), source_.get() + source_alignment, size);
      SCOPED_TRACE(absl::StrCat("Error in memcpy of size: ", size,
                                " with source alignment: ", source_alignment));
      ASSERT_EQ(mem_comparison, 0);
      absl::crc32c_t baseline_crc = absl::ExtendCrc32c(
          initial_crc,
          absl::string_view(
              static_cast<char*>(source_.get()) + source_alignment, size));
      ASSERT_EQ(baseline_crc, experiment_crc);
    }
  }
}

TEST_P(x86ParamTest, SmallCorrectnessCheckDestAlignment) {
  constexpr size_t kTestSizes[] = {0, 100, 255, 512, 1024, 4000, kMaxCopySize};

  for (size_t dest_alignment = 0; dest_alignment < kAlignment;
       dest_alignment++) {
    for (auto size : kTestSizes) {
      char* base_data = static_cast<char*>(source_.get());
      for (size_t i = 0; i < size; i++) {
        *(base_data + i) =
            static_cast<char>(absl::Uniform<unsigned char>(gen_));
      }
      absl::crc32c_t initial_crc =
          absl::crc32c_t{absl::Uniform<uint32_t>(gen_)};
      absl::crc32c_t experiment_crc =
          engine_->Compute(destination_.get() + dest_alignment, source_.get(),
                           size, initial_crc);
      // Check the memory region to make sure it is the same
      int mem_comparison =
          memcmp(destination_.get() + dest_alignment, source_.get(), size);
      SCOPED_TRACE(absl::StrCat("Error in memcpy of size: ", size,
                                " with dest alignment: ", dest_alignment));
      ASSERT_EQ(mem_comparison, 0);
      absl::crc32c_t baseline_crc = absl::ExtendCrc32c(
          initial_crc,
          absl::string_view(static_cast<char*>(source_.get()), size));
      ASSERT_EQ(baseline_crc, experiment_crc);
    }
  }
}

INSTANTIATE_TEST_SUITE_P(x86ParamTest, x86ParamTest,
                         ::testing::Values(
                             // Tests for configurations that may occur in prod.
                             TestParams{X86, 3, 0}, TestParams{X86, 1, 2},
                             // Fallback test.
                             TestParams{FALLBACK, 0, 0},
                             // Non Temporal
                             TestParams{NONTEMPORAL, 0, 0}));

}  // namespace
