//===-- Benchmark function tests -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "LibcBenchmark.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <chrono>
#include <limits>
#include <optional>
#include <queue>
#include <vector>

using std::chrono::nanoseconds;
using ::testing::ElementsAre;
using ::testing::Field;
using ::testing::IsEmpty;
using ::testing::SizeIs;

namespace llvm {
namespace libc_benchmarks {
namespace {

// A simple parameter provider returning a zero initialized vector of size
// `iterations`.
struct DummyParameterProvider {
  std::vector<char> generateBatch(size_t iterations) {
    return std::vector<char>(iterations);
  }
};

class LibcBenchmark : public ::testing::Test {
public:
  // A Clock interface suitable for testing.
  // - Either it returns 0,
  // - Or a timepoint coming from the `setMeasurements` call.
  Duration now() {
    if (!MaybeTimepoints)
      return {};
    assert(!MaybeTimepoints->empty());
    const Duration timepoint = MaybeTimepoints->front();
    MaybeTimepoints->pop();
    return timepoint;
  }

protected:
  void SetUp() override { Options.Log = BenchmarkLog::Full; }

  void TearDown() override {
    // We make sure all the expected measurements were performed.
    if (MaybeTimepoints)
      EXPECT_THAT(*MaybeTimepoints, IsEmpty());
  }

  BenchmarkResult run() {
    return benchmark(Options, ParameterProvider, DummyFunction, *this);
  }

  void setMeasurements(llvm::ArrayRef<Duration> Durations) {
    MaybeTimepoints.emplace(); // Create the optional value.
    Duration CurrentTime = nanoseconds(1);
    for (const auto &Duration : Durations) {
      MaybeTimepoints->push(CurrentTime);
      CurrentTime += Duration;
      MaybeTimepoints->push(CurrentTime);
      CurrentTime += nanoseconds(1);
    }
  }

  BenchmarkOptions Options;

private:
  DummyParameterProvider ParameterProvider;
  static char DummyFunction(char Payload) { return Payload; }
  std::optional<std::queue<Duration>> MaybeTimepoints;
};

TEST_F(LibcBenchmark, MaxSamplesReached) {
  Options.MaxSamples = 1;
  const auto Result = run();
  EXPECT_THAT(Result.MaybeBenchmarkLog->size(), 1);
  EXPECT_THAT(Result.TerminationStatus, BenchmarkStatus::MaxSamplesReached);
}

TEST_F(LibcBenchmark, MaxDurationReached) {
  Options.MaxDuration = nanoseconds(10);
  setMeasurements({nanoseconds(11)});
  const auto Result = run();
  EXPECT_THAT(Result.MaybeBenchmarkLog->size(), 1);
  EXPECT_THAT(Result.TerminationStatus, BenchmarkStatus::MaxDurationReached);
}

TEST_F(LibcBenchmark, MaxIterationsReached) {
  Options.InitialIterations = 1;
  Options.MaxIterations = 20;
  Options.ScalingFactor = 2;
  Options.Epsilon = 0; // unreachable.
  const auto Result = run();
  EXPECT_THAT(*Result.MaybeBenchmarkLog,
              ElementsAre(Field(&BenchmarkState::LastSampleIterations, 1),
                          Field(&BenchmarkState::LastSampleIterations, 2),
                          Field(&BenchmarkState::LastSampleIterations, 4),
                          Field(&BenchmarkState::LastSampleIterations, 8),
                          Field(&BenchmarkState::LastSampleIterations, 16),
                          Field(&BenchmarkState::LastSampleIterations, 32)));
  EXPECT_THAT(Result.MaybeBenchmarkLog->size(), 6);
  EXPECT_THAT(Result.TerminationStatus, BenchmarkStatus::MaxIterationsReached);
}

TEST_F(LibcBenchmark, MinSamples) {
  Options.MinSamples = 4;
  Options.ScalingFactor = 2;
  Options.Epsilon = std::numeric_limits<double>::max(); // always reachable.
  setMeasurements(
      {nanoseconds(1), nanoseconds(2), nanoseconds(4), nanoseconds(8)});
  const auto Result = run();
  EXPECT_THAT(*Result.MaybeBenchmarkLog,
              ElementsAre(Field(&BenchmarkState::LastSampleIterations, 1),
                          Field(&BenchmarkState::LastSampleIterations, 2),
                          Field(&BenchmarkState::LastSampleIterations, 4),
                          Field(&BenchmarkState::LastSampleIterations, 8)));
  EXPECT_THAT(Result.MaybeBenchmarkLog->size(), 4);
  EXPECT_THAT(Result.TerminationStatus, BenchmarkStatus::PrecisionReached);
}

TEST_F(LibcBenchmark, Epsilon) {
  Options.MinSamples = 4;
  Options.ScalingFactor = 2;
  Options.Epsilon = std::numeric_limits<double>::max(); // always reachable.
  setMeasurements(
      {nanoseconds(1), nanoseconds(2), nanoseconds(4), nanoseconds(8)});
  const auto Result = run();
  EXPECT_THAT(*Result.MaybeBenchmarkLog,
              ElementsAre(Field(&BenchmarkState::LastSampleIterations, 1),
                          Field(&BenchmarkState::LastSampleIterations, 2),
                          Field(&BenchmarkState::LastSampleIterations, 4),
                          Field(&BenchmarkState::LastSampleIterations, 8)));
  EXPECT_THAT(Result.MaybeBenchmarkLog->size(), 4);
  EXPECT_THAT(Result.TerminationStatus, BenchmarkStatus::PrecisionReached);
}

TEST(ArrayRefLoop, Cycle) {
  std::array<int, 2> array = {1, 2};
  EXPECT_THAT(cycle(array, 0), ElementsAre());
  EXPECT_THAT(cycle(array, 1), ElementsAre(1));
  EXPECT_THAT(cycle(array, 2), ElementsAre(1, 2));
  EXPECT_THAT(cycle(array, 3), ElementsAre(1, 2, 1));
  EXPECT_THAT(cycle(array, 4), ElementsAre(1, 2, 1, 2));
  EXPECT_THAT(cycle(array, 5), ElementsAre(1, 2, 1, 2, 1));
}

TEST(ByteConstrainedArray, Simple) {
  EXPECT_THAT((ByteConstrainedArray<char, 17>()), SizeIs(17));
  EXPECT_THAT((ByteConstrainedArray<uint16_t, 17>()), SizeIs(8));
  EXPECT_THAT((ByteConstrainedArray<uint32_t, 17>()), SizeIs(4));
  EXPECT_THAT((ByteConstrainedArray<uint64_t, 17>()), SizeIs(2));

  EXPECT_LE(sizeof(ByteConstrainedArray<char, 17>), 17U);
  EXPECT_LE(sizeof(ByteConstrainedArray<uint16_t, 17>), 17U);
  EXPECT_LE(sizeof(ByteConstrainedArray<uint32_t, 17>), 17U);
  EXPECT_LE(sizeof(ByteConstrainedArray<uint64_t, 17>), 17U);
}

TEST(ByteConstrainedArray, Cycle) {
  ByteConstrainedArray<uint64_t, 17> TwoValues{{1UL, 2UL}};
  EXPECT_THAT(cycle(TwoValues, 5), ElementsAre(1, 2, 1, 2, 1));
}
} // namespace
} // namespace libc_benchmarks
} // namespace llvm
