/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * 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
 *
 *      http://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 "benchmark.h"
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <inttypes.h>
#include <time.h>
#include <map>

static int64_t g_flops_processed;
static int64_t g_benchmark_total_time_ns;
static int64_t g_benchmark_start_time_ns;
typedef std::map<std::string, ::testing::Benchmark*> BenchmarkMap;
typedef BenchmarkMap::iterator BenchmarkMapIt;

BenchmarkMap& gBenchmarks() {
  static BenchmarkMap g_benchmarks;
  return g_benchmarks;
}

static int g_name_column_width = 20;

static int Round(int n) {
  int base = 1;
  while (base * 10 < n) {
    base *= 10;
  }
  if (n < 2 * base) {
    return 2 * base;
  }
  if (n < 5 * base) {
    return 5 * base;
  }
  return 10 * base;
}

#ifdef __APPLE__
#include <mach/mach_time.h>
static mach_timebase_info_data_t g_time_info;
static void __attribute__((constructor)) init_info() { mach_timebase_info(&g_time_info); }
#endif

static int64_t NanoTime() {
#if defined(__APPLE__)
  uint64_t t = mach_absolute_time();
  return t * g_time_info.numer / g_time_info.denom;
#else
  struct timespec t;
  t.tv_sec = t.tv_nsec = 0;
  clock_gettime(CLOCK_MONOTONIC, &t);
  return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
#endif
}

namespace testing {
Benchmark* Benchmark::Arg(int arg) {
  args_.push_back(arg);
  return this;
}

Benchmark* Benchmark::Range(int lo, int hi) {
  const int kRangeMultiplier = 8;
  if (hi < lo) {
    int temp = hi;
    hi = lo;
    lo = temp;
  }
  while (lo < hi) {
    args_.push_back(lo);
    lo *= kRangeMultiplier;
  }
  // We always run the hi number.
  args_.push_back(hi);
  return this;
}

const char* Benchmark::Name() { return name_; }
bool Benchmark::ShouldRun(int argc, char* argv[]) {
  if (argc == 1) {
    return true;  // With no arguments, we run all benchmarks.
  }
  // Otherwise, we interpret each argument as a regular expression and
  // see if any of our benchmarks match.
  for (int i = 1; i < argc; i++) {
    regex_t re;
    if (regcomp(&re, argv[i], 0) != 0) {
      fprintf(stderr, "couldn't compile \"%s\" as a regular expression!\n", argv[i]);
      exit(EXIT_FAILURE);
    }
    int match = regexec(&re, name_, 0, NULL, 0);
    regfree(&re);
    if (match != REG_NOMATCH) {
      return true;
    }
  }
  return false;
}
void Benchmark::Register(const char* name, void (*fn)(int), void (*fn_range)(int, int)) {
  name_ = name;
  fn_ = fn;
  fn_range_ = fn_range;
  if (fn_ == NULL && fn_range_ == NULL) {
    fprintf(stderr, "%s: missing function\n", name_);
    exit(EXIT_FAILURE);
  }
  gBenchmarks().insert(std::make_pair(name, this));
}
void Benchmark::Run() {
  if (fn_ != NULL) {
    RunWithArg(0);
  } else {
    if (args_.empty()) {
      fprintf(stderr, "%s: no args!\n", name_);
      exit(EXIT_FAILURE);
    }
    for (size_t i = 0; i < args_.size(); ++i) {
      RunWithArg(args_[i]);
    }
  }
}
void Benchmark::RunRepeatedlyWithArg(int iterations, int arg) {
  g_flops_processed = 0;
  g_benchmark_total_time_ns = 0;
  g_benchmark_start_time_ns = NanoTime();
  if (fn_ != NULL) {
    fn_(iterations);
  } else {
    fn_range_(iterations, arg);
  }
  if (g_benchmark_start_time_ns != 0) {
    g_benchmark_total_time_ns += NanoTime() - g_benchmark_start_time_ns;
  }
}
void Benchmark::RunWithArg(int arg) {
  // run once in case it's expensive
  int iterations = 1;
  RunRepeatedlyWithArg(iterations, arg);
  while (g_benchmark_total_time_ns < 1e9 && iterations < 1e9) {
    int last = iterations;
    if (g_benchmark_total_time_ns / iterations == 0) {
      iterations = 1e9;
    } else {
      iterations = 1e9 / (g_benchmark_total_time_ns / iterations);
    }
    iterations = std::max(last + 1, std::min(iterations + iterations / 2, 100 * last));
    iterations = Round(iterations);
    RunRepeatedlyWithArg(iterations, arg);
  }
  char throughput[100];
  throughput[0] = '\0';
  if (g_benchmark_total_time_ns > 0 && g_flops_processed > 0) {
    double mflops_processed = static_cast<double>(g_flops_processed) / 1e6;
    double seconds = static_cast<double>(g_benchmark_total_time_ns) / 1e9;
    snprintf(throughput, sizeof(throughput), " %8.2f MFlops/s", mflops_processed / seconds);
  }
  char full_name[100];
  if (fn_range_ != NULL) {
    if (arg >= (1 << 20)) {
      snprintf(full_name, sizeof(full_name), "%s/%dM", name_, arg / (1 << 20));
    } else if (arg >= (1 << 10)) {
      snprintf(full_name, sizeof(full_name), "%s/%dK", name_, arg / (1 << 10));
    } else {
      snprintf(full_name, sizeof(full_name), "%s/%d", name_, arg);
    }
  } else {
    snprintf(full_name, sizeof(full_name), "%s", name_);
  }
  printf("%-*s %10d %10" PRId64 "%s\n", g_name_column_width, full_name, iterations,
         g_benchmark_total_time_ns / iterations, throughput);
  fflush(stdout);
}
}  // namespace testing
void SetBenchmarkFlopsProcessed(int64_t x) { g_flops_processed = x; }
void StopBenchmarkTiming() {
  if (g_benchmark_start_time_ns != 0) {
    g_benchmark_total_time_ns += NanoTime() - g_benchmark_start_time_ns;
  }
  g_benchmark_start_time_ns = 0;
}
void StartBenchmarkTiming() {
  if (g_benchmark_start_time_ns == 0) {
    g_benchmark_start_time_ns = NanoTime();
  }
}
int main(int argc, char* argv[]) {
  if (gBenchmarks().empty()) {
    fprintf(stderr, "No benchmarks registered!\n");
    exit(EXIT_FAILURE);
  }
  for (BenchmarkMapIt it = gBenchmarks().begin(); it != gBenchmarks().end(); ++it) {
    int name_width = static_cast<int>(strlen(it->second->Name()));
    g_name_column_width = std::max(g_name_column_width, name_width);
  }
  bool need_header = true;
  for (BenchmarkMapIt it = gBenchmarks().begin(); it != gBenchmarks().end(); ++it) {
    ::testing::Benchmark* b = it->second;
    if (b->ShouldRun(argc, argv)) {
      if (need_header) {
        printf("%-*s %10s %10s\n", g_name_column_width, "", "iterations", "ns/op");
        fflush(stdout);
        need_header = false;
      }
      b->Run();
    }
  }
  if (need_header) {
    fprintf(stderr, "No matching benchmarks!\n");
    fprintf(stderr, "Available benchmarks:\n");
    for (BenchmarkMapIt it = gBenchmarks().begin(); it != gBenchmarks().end(); ++it) {
      fprintf(stderr, "  %s\n", it->second->Name());
    }
    exit(EXIT_FAILURE);
  }
  return 0;
}
