#include "benchmark/benchmark.h"
#include "GenerateInput.hpp"
#include "test_iterators.h"
#include "filesystem_include.hpp"

static const size_t TestNumInputs = 1024;


template <class GenInputs>
void BM_PathConstructString(benchmark::State &st, GenInputs gen) {
  using fs::path;
  const auto in = gen(st.range(0));
  path PP;
  for (auto& Part : in)
    PP /= Part;
  benchmark::DoNotOptimize(PP.native().data());
  while (st.KeepRunning()) {
    const path P(PP.native());
    benchmark::DoNotOptimize(P.native().data());
  }
  st.SetComplexityN(st.range(0));
}
BENCHMARK_CAPTURE(BM_PathConstructString, large_string,
  getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();


template <class GenInputs>
void BM_PathConstructCStr(benchmark::State &st, GenInputs gen) {
  using fs::path;
  const auto in = gen(st.range(0));
  path PP;
  for (auto& Part : in)
    PP /= Part;
  benchmark::DoNotOptimize(PP.native().data());
  while (st.KeepRunning()) {
    const path P(PP.native().c_str());
    benchmark::DoNotOptimize(P.native().data());
  }
}
BENCHMARK_CAPTURE(BM_PathConstructCStr, large_string,
  getRandomStringInputs)->Arg(TestNumInputs);


template <template <class...> class ItType, class GenInputs>
void BM_PathConstructIter(benchmark::State &st, GenInputs gen) {
  using fs::path;
  using Iter = ItType<std::string::const_iterator>;
  const auto in = gen(st.range(0));
  path PP;
  for (auto& Part : in)
    PP /= Part;
  auto Start = Iter(PP.native().begin());
  auto End = Iter(PP.native().end());
  benchmark::DoNotOptimize(PP.native().data());
  benchmark::DoNotOptimize(Start);
  benchmark::DoNotOptimize(End);
  while (st.KeepRunning()) {
    const path P(Start, End);
    benchmark::DoNotOptimize(P.native().data());
  }
  st.SetComplexityN(st.range(0));
}
template <class GenInputs>
void BM_PathConstructInputIter(benchmark::State &st, GenInputs gen) {
  BM_PathConstructIter<input_iterator>(st, gen);
}
template <class GenInputs>
void BM_PathConstructForwardIter(benchmark::State &st, GenInputs gen) {
  BM_PathConstructIter<forward_iterator>(st, gen);
}
BENCHMARK_CAPTURE(BM_PathConstructInputIter, large_string,
  getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
BENCHMARK_CAPTURE(BM_PathConstructForwardIter, large_string,
  getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();


template <class GenInputs>
void BM_PathIterateMultipleTimes(benchmark::State &st, GenInputs gen) {
  using fs::path;
  const auto in = gen(st.range(0));
  path PP;
  for (auto& Part : in)
    PP /= Part;
  benchmark::DoNotOptimize(PP.native().data());
  while (st.KeepRunning()) {
    for (auto &E : PP) {
      benchmark::DoNotOptimize(E.native().data());
    }
    benchmark::ClobberMemory();
  }
  st.SetComplexityN(st.range(0));
}
BENCHMARK_CAPTURE(BM_PathIterateMultipleTimes, iterate_elements,
  getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();


template <class GenInputs>
void BM_PathIterateOnce(benchmark::State &st, GenInputs gen) {
  using fs::path;
  const auto in = gen(st.range(0));
  path PP;
  for (auto& Part : in)
    PP /= Part;
  benchmark::DoNotOptimize(PP.native().data());
  while (st.KeepRunning()) {
    const path P = PP.native();
    for (auto &E : P) {
      benchmark::DoNotOptimize(E.native().data());
    }
    benchmark::ClobberMemory();
  }
  st.SetComplexityN(st.range(0));
}
BENCHMARK_CAPTURE(BM_PathIterateOnce, iterate_elements,
  getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();

template <class GenInputs>
void BM_PathIterateOnceBackwards(benchmark::State &st, GenInputs gen) {
  using fs::path;
  const auto in = gen(st.range(0));
  path PP;
  for (auto& Part : in)
    PP /= Part;
  benchmark::DoNotOptimize(PP.native().data());
  while (st.KeepRunning()) {
    const path P = PP.native();
    const auto B = P.begin();
    auto I = P.end();
    while (I != B) {
      --I;
      benchmark::DoNotOptimize(*I);
    }
    benchmark::DoNotOptimize(*I);
  }
}
BENCHMARK_CAPTURE(BM_PathIterateOnceBackwards, iterate_elements,
  getRandomStringInputs)->Arg(TestNumInputs);

static fs::path getRandomPaths(int NumParts, int PathLen) {
  fs::path Result;
  while (NumParts--) {
    std::string Part = getRandomString(PathLen);
    Result /= Part;
  }
  return Result;
}

template <class GenInput>
void BM_LexicallyNormal(benchmark::State &st, GenInput gen, size_t PathLen) {
  using fs::path;
  auto In = gen(st.range(0), PathLen);
  benchmark::DoNotOptimize(&In);
  while (st.KeepRunning()) {
    benchmark::DoNotOptimize(In.lexically_normal());
  }
  st.SetComplexityN(st.range(0));
}
BENCHMARK_CAPTURE(BM_LexicallyNormal, small_path,
  getRandomPaths, /*PathLen*/5)->RangeMultiplier(2)->Range(2, 256)->Complexity();
BENCHMARK_CAPTURE(BM_LexicallyNormal, large_path,
  getRandomPaths, /*PathLen*/32)->RangeMultiplier(2)->Range(2, 256)->Complexity();

BENCHMARK_MAIN();
