#include <iostream>
#include <Kokkos_Core.hpp>
#include <RevisionInfo.hpp>
#include <rang.hpp>

#include <CLI/CLI.hpp>

int main(int argc, char *argv[])
{
  CLI::App app{"Pastis help"};

  long number = 1000;
  app.add_option("-n,--number", number, "A big integer");

  CLI11_PARSE(app, argc, argv);

  std::cout << "-------------------- "
	    << rang::fg::green
	    << "git info"
	    << rang::fg::reset
	    <<" -------------------------"
	    << '\n';
  std::cout << "version: " << rang::fg::reset
	    << rang::style::bold << RevisionInfo::version() << rang::style::reset << '\n';
  std::cout << "HEAD: " << rang::style::bold << RevisionInfo::head() << rang::style::reset << '\n';
  std::cout << "hash: " << rang::style::bold << RevisionInfo::hash() << rang::style::reset << "  (";
  if (RevisionInfo::isClean()) {
    std::cout << rang::fgB::green << "clean" << rang::fg::reset;
  } else {
    std::cout << rang::fgB::red << "dirty" << rang::fg::reset; 
  }
  std::cout << ")\n";
  std::cout << "-------------------------------------------------------\n";

  Kokkos::initialize(argc, argv);
  Kokkos::DefaultExecutionSpace::print_configuration(std::cout);

  // if (argc < 2) {
  //   fprintf(stderr, "Usage: %s [<kokkos_options>] <size>\n", argv[0]);
  //   Kokkos::finalize();
  //   exit(1);
  // }

  const long& n = number;
  std::cout << "Number of even integers from 0 to " << n - 1 << '\n';

  Kokkos::Timer timer;
  timer.reset();

  // Compute the number of even integers from 0 to n-1, in parallel.
  long count = 0;
  Kokkos::parallel_reduce(n, [=] (const long i, long& lcount) {
    lcount += (i % 2) == 0;
  }, count);

  double count_time = timer.seconds();
  std::cout << "  Parallel: " << count << " " << rang::style::bold << count_time << rang::style::reset << '\n';

  timer.reset();

  // Compare to a sequential loop.
  long seq_count = 0;
  for (long i = 0; i < n; ++i) {
    seq_count += (i % 2) == 0;
  }

  count_time = timer.seconds();
  std::cout << "Sequential: " << seq_count << ' ' << rang::style::bold << count_time << rang::style::reset << '\n';
  Kokkos::finalize();

  return (count == seq_count) ? 0 : -1;
}