#include "walltime.h"

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

#include <atomic>
#include <limits>

#include "benchmark/macros.h"
#include "cycleclock.h"
#include "sysinfo.h"

namespace benchmark {
namespace walltime {
namespace {
const double kMaxErrorInterval = 100e-6;

std::atomic<bool> initialized(false);
WallTime base_walltime = 0.0;
int64_t base_cycletime = 0;
int64_t cycles_per_second;
double seconds_per_cycle;
uint32_t last_adjust_time = 0;
std::atomic<int32_t> drift_adjust(0);
int64_t max_interval_cycles = 0;

// Helper routines to load/store a float from an AtomicWord. Required because
// g++ < 4.7 doesn't support std::atomic<float> correctly. I cannot wait to get
// rid of this horror show.
inline void SetDrift(float f) {
  int32_t w;
  memcpy(&w, &f, sizeof(f));
  std::atomic_store(&drift_adjust, w);
}

inline float GetDrift() {
  float f;
  int32_t w = std::atomic_load(&drift_adjust);
  memcpy(&f, &w, sizeof(f));
  return f;
}

static_assert(sizeof(float) <= sizeof(int32_t),
              "type sizes don't allow the drift_adjust hack");

WallTime Slow() {
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return tv.tv_sec + tv.tv_usec * 1e-6;
}

bool SplitTimezone(WallTime value, bool local, struct tm* t,
                   double* subsecond) {
  memset(t, 0, sizeof(*t));
  if ((value < 0) || (value > std::numeric_limits<time_t>::max())) {
    *subsecond = 0.0;
    return false;
  }
  const time_t whole_time = static_cast<time_t>(value);
  *subsecond = value - whole_time;
  if (local)
    localtime_r(&whole_time, t);
  else
    gmtime_r(&whole_time, t);
  return true;
}
}  // end namespace

// This routine should be invoked to initialize walltime.
// It is not intended for general purpose use.
void Initialize() {
  CHECK(!std::atomic_load(&initialized));
  cycles_per_second = static_cast<int64_t>(CyclesPerSecond());
  CHECK(cycles_per_second != 0);
  seconds_per_cycle = 1.0 / cycles_per_second;
  max_interval_cycles = static_cast<int64_t>(
      cycles_per_second * kMaxErrorInterval);
  do {
    base_cycletime = cycleclock::Now();
    base_walltime = Slow();
  } while (cycleclock::Now() - base_cycletime > max_interval_cycles);
  // We are now sure that "base_walltime" and "base_cycletime" were produced
  // within kMaxErrorInterval of one another.

  SetDrift(0.0);
  last_adjust_time = static_cast<uint32_t>(uint64_t(base_cycletime) >> 32);
  std::atomic_store(&initialized, true);
}

WallTime Now() {
  if (!std::atomic_load(&initialized))
    return Slow();

  WallTime now = 0.0;
  WallTime result = 0.0;
  int64_t ct = 0;
  uint32_t top_bits = 0;
  do {
    ct = cycleclock::Now();
    int64_t cycle_delta = ct - base_cycletime;
    result = base_walltime + cycle_delta * seconds_per_cycle;

    top_bits = static_cast<uint32_t>(uint64_t(ct) >> 32);
    // Recompute drift no more often than every 2^32 cycles.
    // I.e., @2GHz, ~ every two seconds
    if (top_bits == last_adjust_time) { // don't need to recompute drift
      return result + GetDrift();
    }

    now = Slow();
  } while (cycleclock::Now() - ct > max_interval_cycles);
  // We are now sure that "now" and "result" were produced within
  // kMaxErrorInterval of one another.

  SetDrift(now - result);
  last_adjust_time = top_bits;
  return now;
}

std::string Print(WallTime time, const char *format, bool local,
                  int *remainder_us) {
  char storage[32];
  struct tm split;
  double subsecond;
  if (!SplitTimezone(time, local, &split, &subsecond)) {
    snprintf(storage, sizeof(storage), "Invalid time: %f", time);
  } else {
    if (remainder_us != NULL) {
      *remainder_us = static_cast<int>((subsecond * 1000000) + 0.5);
      if (*remainder_us > 999999) *remainder_us = 999999;
      if (*remainder_us < 0)      *remainder_us = 0;
    }
    strftime(storage, sizeof(storage), format, &split);
  }
  return std::string(storage);
}
}  // end namespace walltime
}  // end namespace benchmark
