#include <mutex>
#include <random>
#include <set>
#include <string>
#include <thread>
#include <vector>

#include "../src/perf_counters.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

#ifndef GTEST_SKIP
struct MsgHandler {
  void operator=(std::ostream&) {}
};
#define GTEST_SKIP() return MsgHandler() = std::cout
#endif

using benchmark::internal::PerfCounters;
using benchmark::internal::PerfCountersMeasurement;
using benchmark::internal::PerfCounterValues;
using ::testing::AllOf;
using ::testing::Gt;
using ::testing::Lt;

namespace {
const char kGenericPerfEvent1[] = "CYCLES";
const char kGenericPerfEvent2[] = "INSTRUCTIONS";

std::set<std::string> UniqueCounterNames(const PerfCounters& counters) {
  return {counters.names().begin(), counters.names().end()};
}

bool HasRequiredPerfCounters(const std::vector<std::string>& names) {
  if (!PerfCounters::kSupported) {
    return false;
  }
  auto counters = PerfCounters::Create(names);
  auto actual_names = UniqueCounterNames(counters);
  for (const auto& name : names) {
    if (actual_names.find(name) == actual_names.end()) {
      return false;
    }
  }
  return true;
}

TEST(PerfCountersTest, Init) {
  EXPECT_EQ(PerfCounters::Initialize(), PerfCounters::kSupported);
}

TEST(PerfCountersTest, OneCounter) {
  if (!HasRequiredPerfCounters({kGenericPerfEvent1})) {
    GTEST_SKIP() << "Requested performance counters are not available.";
  }
  auto counter = PerfCounters::Create({kGenericPerfEvent1});
  EXPECT_EQ(UniqueCounterNames(counter).size(), 1);
}

TEST(PerfCountersTest, NegativeTest) {
  if (!PerfCounters::kSupported) {
    EXPECT_FALSE(PerfCounters::Initialize());
    return;
  }
  if (!HasRequiredPerfCounters({kGenericPerfEvent2, kGenericPerfEvent1})) {
    GTEST_SKIP() << "Requested performance counters are not available.";
  }
  // Safety checks
  // Create() will always create a valid object, even if passed no or
  // wrong arguments as the new behavior is to warn and drop unsupported
  // counters
  EXPECT_EQ(PerfCounters::Create({}).num_counters(), 0);
  EXPECT_EQ(PerfCounters::Create({""}).num_counters(), 0);
  EXPECT_EQ(PerfCounters::Create({"not a counter name"}).num_counters(), 0);
  {
    // Try sneaking in a bad egg to see if it is filtered out. The
    // number of counters has to be two, not zero
    auto counter =
        PerfCounters::Create({kGenericPerfEvent2, "", kGenericPerfEvent1});
    auto names = UniqueCounterNames(counter);
    EXPECT_EQ(names.size(), 2);
    EXPECT_EQ(names,
              std::set<std::string>({kGenericPerfEvent2, kGenericPerfEvent1}));
  }
  {
    // Try sneaking in an outrageous counter, like a fat finger mistake
    auto counter = PerfCounters::Create(
        {kGenericPerfEvent2, "not a counter name", kGenericPerfEvent1});
    auto names = UniqueCounterNames(counter);
    EXPECT_EQ(names.size(), 2);
    EXPECT_EQ(names,
              std::set<std::string>({kGenericPerfEvent2, kGenericPerfEvent1}));
  }
  {
    // Finally try a golden input - it should like both of them
    EXPECT_EQ(UniqueCounterNames(PerfCounters::Create(
                                     {kGenericPerfEvent1, kGenericPerfEvent2}))
                  .size(),
              2);
  }
  {
    // Add a bad apple in the end of the chain to check the edges
    auto counter = PerfCounters::Create(
        {kGenericPerfEvent1, kGenericPerfEvent2, "bad event name"});
    auto names = UniqueCounterNames(counter);
    EXPECT_EQ(names.size(), 2);
    EXPECT_EQ(names,
              std::set<std::string>({kGenericPerfEvent1, kGenericPerfEvent2}));
  }
}

static std::map<std::string, uint64_t> SnapshotAndCombine(
    PerfCounters& counters) {
  PerfCounterValues values(counters.num_counters());
  std::map<std::string, uint64_t> value_map;

  if (counters.Snapshot(&values)) {
    for (size_t i = 0; i != counters.num_counters(); ++i) {
      value_map[counters.names()[i]] += values[i];
    }
  }
  return value_map;
}

TEST(PerfCountersTest, Read1Counter) {
  if (!HasRequiredPerfCounters({kGenericPerfEvent1})) {
    GTEST_SKIP() << "Requested performance counters are not available.";
  }
  auto counters = PerfCounters::Create({kGenericPerfEvent1});
  auto values1 = SnapshotAndCombine(counters);
  EXPECT_EQ(values1.size(), 1);
  EXPECT_GT(values1.begin()->second, 0);
  auto values2 = SnapshotAndCombine(counters);
  EXPECT_EQ(values2.size(), 1);
  EXPECT_GT(values2.begin()->second, 0);
  EXPECT_GT(values2.begin()->second, values1.begin()->second);
}

TEST(PerfCountersTest, Read1CounterEachCPU) {
  if (!HasRequiredPerfCounters({kGenericPerfEvent1})) {
    GTEST_SKIP() << "Requested performance counters are not available.";
  }
#ifdef __linux__
  cpu_set_t saved_set;
  if (sched_getaffinity(0, sizeof(saved_set), &saved_set) != 0) {
    // This can happen e.g. if there are more than CPU_SETSIZE CPUs.
    GTEST_SKIP() << "Could not save CPU affinity mask.";
  }

  for (size_t cpu = 0; cpu != CPU_SETSIZE; ++cpu) {
    cpu_set_t set;
    CPU_ZERO(&set);
    CPU_SET(cpu, &set);
    if (sched_setaffinity(0, sizeof(set), &set) != 0) {
      break;
    }

    auto counters = PerfCounters::Create({kGenericPerfEvent1});
    auto values1 = SnapshotAndCombine(counters);
    EXPECT_EQ(values1.size(), 1);
    EXPECT_GT(values1.begin()->second, 0);
    auto values2 = SnapshotAndCombine(counters);
    EXPECT_EQ(values2.size(), 1);
    EXPECT_GT(values2.begin()->second, 0);
    EXPECT_GT(values2.begin()->second, values1.begin()->second);
  }

  EXPECT_EQ(sched_setaffinity(0, sizeof(saved_set), &saved_set), 0);
#else
  GTEST_SKIP() << "Test skipped on non-Linux.";
#endif
}

TEST(PerfCountersTest, Read2Counters) {
  if (!HasRequiredPerfCounters({kGenericPerfEvent1, kGenericPerfEvent2})) {
    GTEST_SKIP() << "Requested performance counters are not available.";
  }
  auto counters =
      PerfCounters::Create({kGenericPerfEvent1, kGenericPerfEvent2});
  auto values1 = SnapshotAndCombine(counters);
  EXPECT_EQ(values1.size(), 2);
  for (auto& kv : values1) {
    EXPECT_GT(kv.second, 0);
  }
  auto values2 = SnapshotAndCombine(counters);
  EXPECT_EQ(values1.size(), 2);
  for (auto& kv : values2) {
    EXPECT_GT(kv.second, 0);
    EXPECT_GT(kv.second, values1[kv.first]);
  }
}

TEST(PerfCountersTest, ReopenExistingCounters) {
  // This test works in recent and old Intel hardware, Pixel 3, and Pixel 6.
  // However we cannot make assumptions beyond 2 HW counters due to Pixel 6.
  if (!HasRequiredPerfCounters({kGenericPerfEvent1})) {
    GTEST_SKIP() << "Requested performance counters are not available.";
  }
  std::vector<std::string> kMetrics({kGenericPerfEvent1});
  std::vector<PerfCounters> counters(2);
  for (auto& counter : counters) {
    counter = PerfCounters::Create(kMetrics);
  }
  PerfCounterValues values(counters[0].num_counters());
  EXPECT_TRUE(counters[0].Snapshot(&values));
  EXPECT_TRUE(counters[1].Snapshot(&values));
}

TEST(PerfCountersTest, CreateExistingMeasurements) {
  // The test works (i.e. causes read to fail) for the assumptions
  // about hardware capabilities (i.e. small number (2) hardware
  // counters) at this date,
  // the same as previous test ReopenExistingCounters.
  if (!PerfCounters::kSupported) {
    GTEST_SKIP() << "Test skipped because libpfm is not supported.";
  }

  // This means we will try 10 counters but we can only guarantee
  // for sure at this time that only 3 will work. Perhaps in the future
  // we could use libpfm to query for the hardware limits on this
  // particular platform.
  const int kMaxCounters = 10;
  const int kMinValidCounters = 2;

  // Let's use a ubiquitous counter that is guaranteed to work
  // on all platforms
  const std::vector<std::string> kMetrics{"cycles"};
  if (!HasRequiredPerfCounters(kMetrics)) {
    GTEST_SKIP() << "Requested performance counters are not available.";
  }

  // Cannot create a vector of actual objects because the
  // copy constructor of PerfCounters is deleted - and so is
  // implicitly deleted on PerfCountersMeasurement too
  std::vector<std::unique_ptr<PerfCountersMeasurement>>
      perf_counter_measurements;

  perf_counter_measurements.reserve(kMaxCounters);
  for (int j = 0; j < kMaxCounters; ++j) {
    perf_counter_measurements.emplace_back(
        new PerfCountersMeasurement(kMetrics));
  }

  std::vector<std::pair<std::string, double>> measurements;

  // Start all counters together to see if they hold
  size_t max_counters = kMaxCounters;
  for (size_t i = 0; i < kMaxCounters; ++i) {
    auto& counter(*perf_counter_measurements[i]);
    std::set<std::string> names{counter.names().begin(), counter.names().end()};
    EXPECT_EQ(names.size(), 1);
    if (!counter.Start()) {
      max_counters = i;
      break;
    };
  }

  ASSERT_GE(max_counters, kMinValidCounters);

  // Start all together
  for (size_t i = 0; i < max_counters; ++i) {
    auto& counter(*perf_counter_measurements[i]);
    EXPECT_TRUE(counter.Stop(measurements) || (i >= kMinValidCounters));
  }

  // Start/stop individually
  for (size_t i = 0; i < max_counters; ++i) {
    auto& counter(*perf_counter_measurements[i]);
    measurements.clear();
    counter.Start();
    EXPECT_TRUE(counter.Stop(measurements) || (i >= kMinValidCounters));
  }
}

// We try to do some meaningful work here but the compiler
// insists in optimizing away our loop so we had to add a
// no-optimize macro. In case it fails, we added some entropy
// to this pool as well.

BENCHMARK_DONT_OPTIMIZE size_t do_work() {
  static std::mt19937 rd{std::random_device{}()};
  static std::uniform_int_distribution<size_t> mrand(0, 10);
  const size_t kNumLoops = 1000000;
  size_t sum = 0;
  for (size_t j = 0; j < kNumLoops; ++j) {
    sum += mrand(rd);
  }
  benchmark::DoNotOptimize(sum);
  return sum;
}

void measure(size_t threadcount, std::map<std::string, uint64_t>* before,
             std::map<std::string, uint64_t>* after) {
  BM_CHECK_NE(before, nullptr);
  BM_CHECK_NE(after, nullptr);
  std::vector<std::thread> threads(threadcount);
  // Because we do not care whether the threads execute concurrently, but we do
  // care that they do all of their work between the SnapshotAndCombine calls,
  // we serialize them with a mutex. See
  // https://github.com/google/benchmark/issues/2173.
  std::mutex mutex;
  auto work = [&mutex]() {
    mutex.lock();
    BM_CHECK(do_work() > 1000);
    mutex.unlock();
  };

  // We need to first set up the counters, then start the threads, so the
  // threads would inherit the counters. But later, we need to first destroy
  // the thread pool (so all the work finishes), then measure the counters. So
  // the scopes overlap, and we need to explicitly control the scope of the
  // threadpool.
  auto counters =
      PerfCounters::Create({kGenericPerfEvent1, kGenericPerfEvent2});
  mutex.lock();
  for (auto& t : threads) {
    t = std::thread(work);
  }
  *before = SnapshotAndCombine(counters);
  mutex.unlock();
  for (auto& t : threads) {
    t.join();
  }
  *after = SnapshotAndCombine(counters);
}

TEST(PerfCountersTest, MultiThreaded) {
  if (!HasRequiredPerfCounters({kGenericPerfEvent1, kGenericPerfEvent2})) {
    GTEST_SKIP() << "Requested performance counters are not available.";
  }
  std::map<std::string, uint64_t> before, after;

  // Notice that this test will work even if we taskset it to a single CPU
  // In this case the threads will run sequentially
  // Start two threads and measure the number of combined cycles and
  // instructions
  measure(2, &before, &after);
  std::vector<double> Elapsed2Threads{
      static_cast<double>(after[kGenericPerfEvent1] -
                          before[kGenericPerfEvent1]),
      static_cast<double>(after[kGenericPerfEvent2] -
                          before[kGenericPerfEvent2])};

  // Start four threads and measure the number of combined cycles and
  // instructions
  measure(4, &before, &after);
  std::vector<double> Elapsed4Threads{
      static_cast<double>(after[kGenericPerfEvent1] -
                          before[kGenericPerfEvent1]),
      static_cast<double>(after[kGenericPerfEvent2] -
                          before[kGenericPerfEvent2])};

  // The following expectations fail (at least on a beefy workstation with lots
  // of cpus) - it seems that in some circumstances the runtime of 4 threads
  // can even be better than with 2.
  // So instead of expecting 4 threads to be slower, let's just make sure they
  // do not differ too much in general (one is not more than 10x than the
  // other).
  EXPECT_THAT(Elapsed4Threads[0] / Elapsed2Threads[0], AllOf(Gt(0.1), Lt(10)));
  EXPECT_THAT(Elapsed4Threads[1] / Elapsed2Threads[1], AllOf(Gt(0.1), Lt(10)));
}

TEST(PerfCountersTest, HardwareLimits) {
  // The test works (i.e. causes read to fail) for the assumptions
  // about hardware capabilities (i.e. small number (3-4) hardware
  // counters) at this date,
  // the same as previous test ReopenExistingCounters.
  if (!PerfCounters::kSupported) {
    GTEST_SKIP() << "Test skipped because libpfm is not supported.";
  }
  EXPECT_TRUE(PerfCounters::Initialize());

  // Taken from `perf list`, but focusses only on those HW events that actually
  // were reported when running `sudo perf stat -a sleep 10`, intersected over
  // several platforms. All HW events listed in the first command not reported
  // in the second seem to not work. This is sad as we don't really get to test
  // the grouping here (groups can contain up to 6 members)...
  std::vector<std::string> counter_names{
      "cycles",         // leader
      "instructions",   //
      "branch-misses",  //
  };

  // In the off-chance that some of these values are not supported,
  // we filter them out so the test will complete without failure
  // albeit it might not actually test the grouping on that platform
  std::vector<std::string> valid_names;
  for (const std::string& name : counter_names) {
    if (PerfCounters::IsCounterSupported(name)) {
      valid_names.push_back(name);
    }
  }
  PerfCountersMeasurement counter(valid_names);

  std::vector<std::pair<std::string, double>> measurements;

  counter.Start();
  EXPECT_TRUE(counter.Stop(measurements));
}

}  // namespace
