// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.
//
// Author: tkaftal@google.com (Tomasz Kaftal)
//
// The implementation of walltime functionalities.
#ifndef _GNU_SOURCE   // gcc3 at least defines it on the command line
#define _GNU_SOURCE   // Linux wants that for strptime in time.h
#endif

#include "kudu/gutil/walltime.h"

#include <stdio.h>
#include <string.h>

#if defined(__APPLE__)
#include <mach/clock.h>
#include <mach/mach.h>
#endif  // defined(__APPLE__)

#if defined(__APPLE__)
namespace walltime_internal {

GoogleOnceType timebase_info_once = GOOGLE_ONCE_INIT;
mach_timebase_info_data_t timebase_info;

void InitializeTimebaseInfo() {
  CHECK_EQ(KERN_SUCCESS, mach_timebase_info(&timebase_info))
      << "unable to initialize mach_timebase_info";
}
} // namespace walltime_internal
#endif

// This is exactly like mktime() except it is guaranteed to return -1 on
// failure.  Some versions of glibc allow mktime() to return negative
// values which the standard says are undefined.  See the standard at
// http://www.opengroup.org/onlinepubs/007904875/basedefs/xbd_chap04.html
// under the heading "Seconds Since the Epoch".
static inline time_t gmktime(struct tm *tm) {
  time_t rt = mktime(tm);
  return rt < 0 ? time_t(-1) : rt;
}

static void StringAppendStrftime(std::string* dst,
                                 const char* format,
                                 const struct tm* tm) {
  char space[1024];

  int result = strftime(space, sizeof(space), format, tm);

  if ((result >= 0) && (result < sizeof(space))) {
    // It fit
    dst->append(space, result);
    return;
  }

  int length = sizeof(space);
  for (int sanity = 0; sanity < 5; ++sanity) {
    length *= 2;
    auto buf = new char[length];

    result = strftime(buf, length, format, tm);
    if ((result >= 0) && (result < length)) {
      // It fit
      dst->append(buf, result);
      delete[] buf;
      return;
    }

    delete[] buf;
  }

  // sanity failure
  return;
}

// Convert a "struct tm" interpreted as *GMT* into a time_t (technically
// a long since we can't include header files in header files bla bla bla).
// This is basically filling a hole in the standard library.
//
// There are several approaches to mkgmtime() implementation on the net,
// many of them wrong.  Simply reimplementing the logic seems to be the
// simplest and most efficient, though it does reimplement calendar logic.
// The calculation is mostly straightforward; leap years are the main issue.
//
// Like gmktime() this method returns -1 on failure. Negative results
// are considered undefined by the standard so these cases are
// considered failures and thus return -1.
time_t mkgmtime(const struct tm *tm) {
  // Month-to-day offset for non-leap-years.
  static const int month_day[12] =
    {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};

  // Most of the calculation is easy; leap years are the main difficulty.
  int month = tm->tm_mon % 12;
  int year = tm->tm_year + tm->tm_mon / 12;
  if (month < 0) {   // Negative values % 12 are still negative.
    month += 12;
    --year;
  }

  // This is the number of Februaries since 1900.
  const int year_for_leap = (month > 1) ? year + 1 : year;

  time_t rt = tm->tm_sec                           // Seconds
       + 60 * (tm->tm_min                          // Minute = 60 seconds
       + 60 * (tm->tm_hour                         // Hour = 60 minutes
       + 24 * (month_day[month] + tm->tm_mday - 1  // Day = 24 hours
       + 365 * (year - 70)                         // Year = 365 days
       + (year_for_leap - 69) / 4                  // Every 4 years is leap...
       - (year_for_leap - 1) / 100                 // Except centuries...
       + (year_for_leap + 299) / 400)));           // Except 400s.
  return rt < 0 ? -1 : rt;
}

bool WallTime_Parse_Timezone(const char* time_spec,
                             const char* format,
                             const struct tm* default_time,
                             bool local,
                             WallTime* result) {
  struct tm split_time;
  if (default_time) {
     split_time = *default_time;
  } else {
     memset(&split_time, 0, sizeof(split_time));
  }
  const char* parsed = strptime(time_spec, format, &split_time);
  if (parsed == nullptr) return false;

  // If format ends with "%S", match fractional seconds
  double fraction = 0.0;
  char junk;
  if ((*parsed == '.') &&
     (strcmp(format + strlen(format) - 2, "%S") == 0) &&
     (sscanf(parsed, "%lf%c",  // NOLINT(runtime/printf)
             &fraction, &junk) == 1)) {
     parsed = format + strlen(format);   // Parsed it all!
  }
  if (*parsed != '\0') return false;

  // Convert into seconds since epoch.  Adjust so it is interpreted
  // w.r.t. the daylight-saving-state at the specified time.
  split_time.tm_isdst = -1;     // Ask gmktime() to find dst imfo
  time_t ptime;
  if (local) {
    ptime = gmktime(&split_time);
  } else {
    ptime = mkgmtime(&split_time);  // Returns time in GMT instead of local.
  }

  if (ptime == -1) return false;

  *result = ptime;
  *result += fraction;
  return true;
}

WallTime WallTime_Now() {
#if defined(__APPLE__)
  mach_timespec_t ts;
  walltime_internal::GetCurrentTime(&ts);
  return ts.tv_sec + ts.tv_nsec / static_cast<double>(1e9);
#else
  timespec ts;
  clock_gettime(CLOCK_REALTIME, &ts);
  return ts.tv_sec + ts.tv_nsec / static_cast<double>(1e9);
#endif  // defined(__APPLE__)
}

void StringAppendStrftime(std::string* dst,
                          const char* format,
                          time_t when,
                          bool local) {
  struct tm tm;
  bool conversion_error;
  if (local) {
    conversion_error = (localtime_r(&when, &tm) == nullptr);
  } else {
    conversion_error = (gmtime_r(&when, &tm) == nullptr);
  }
  if (conversion_error) {
    // If we couldn't convert the time, don't append anything.
    return;
  }
  StringAppendStrftime(dst, format, &tm);
}

std::string TimestampAsString(time_t timestamp_secs) {
  std::string ret;
  StringAppendStrftime(&ret, "%Y-%m-%d %H:%M:%S %Z", timestamp_secs, true);
  return ret;
}

std::string LocalTimeAsString() {
  return TimestampAsString(time(nullptr));
}
