// Copyright 2015 Google Inc. All rights reserved.
//
// 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 "walltime.h"

#include <sys/time.h>

#include <cstdio>
#include <cstdint>
#include <cstring>
#include <ctime>

#include <atomic>
#include <limits>
#include <type_traits>

#include "check.h"
#include "cycleclock.h"
#include "sysinfo.h"

namespace benchmark {
namespace walltime {
namespace {

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 anonymous namespace


namespace {

class WallTimeImp
{
public:
  WallTime Now();

  static WallTimeImp& GetWallTimeImp() {
    static WallTimeImp imp;
#if __cplusplus >= 201103L
    static_assert(std::is_trivially_destructible<WallTimeImp>::value,
                  "WallTimeImp must be trivially destructible to prevent "
                  "issues with static destruction");
#endif
    return imp;
  }

private:
  WallTimeImp();
  // 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.
  void SetDrift(float f) {
    int32_t w;
    memcpy(&w, &f, sizeof(f));
    std::atomic_store(&drift_adjust_, w);
  }

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

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

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

  static constexpr double kMaxErrorInterval = 100e-6;

  WallTime base_walltime_;
  int64_t base_cycletime_;
  int64_t cycles_per_second_;
  double seconds_per_cycle_;
  uint32_t last_adjust_time_;
  std::atomic<int32_t> drift_adjust_;
  int64_t max_interval_cycles_;

  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(WallTimeImp);
};


WallTime WallTimeImp::Now() {
  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;
}


WallTimeImp::WallTimeImp()
    : base_walltime_(0.0), base_cycletime_(0),
      cycles_per_second_(0), seconds_per_cycle_(0.0),
      last_adjust_time_(0), drift_adjust_(0),
      max_interval_cycles_(0) {
  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);
}

} // end anonymous namespace


WallTime Now()
{
    static WallTimeImp& imp = WallTimeImp::GetWallTimeImp();
    return imp.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 != nullptr) {
      *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
