/*
 * Copyright (C) 2014 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 <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>

#include <private/android_logger.h>

#include "log_portability.h"

LIBLOG_ABI_PRIVATE const char log_time::default_format[] = "%m-%d %H:%M:%S.%q";
LIBLOG_ABI_PRIVATE const timespec log_time::EPOCH = { 0, 0 };

// Add %#q for fractional seconds to standard strptime function

LIBLOG_ABI_PRIVATE char* log_time::strptime(const char* s, const char* format) {
  time_t now;
#ifdef __linux__
  *this = log_time(CLOCK_REALTIME);
  now = tv_sec;
#else
  time(&now);
  tv_sec = now;
  tv_nsec = 0;
#endif

  struct tm* ptm;
#if !defined(_WIN32)
  struct tm tmBuf;
  ptm = localtime_r(&now, &tmBuf);
#else
  ptm = localtime(&now);
#endif

  char fmt[strlen(format) + 1];
  strcpy(fmt, format);

  char* ret = const_cast<char*>(s);
  char* cp;
  for (char* f = cp = fmt;; ++cp) {
    if (!*cp) {
      if (f != cp) {
        ret = ::strptime(ret, f, ptm);
      }
      break;
    }
    if (*cp != '%') {
      continue;
    }
    char* e = cp;
    ++e;
#if (defined(__BIONIC__))
    if (*e == 's') {
      *cp = '\0';
      if (*f) {
        ret = ::strptime(ret, f, ptm);
        if (!ret) {
          break;
        }
      }
      tv_sec = 0;
      while (isdigit(*ret)) {
        tv_sec = tv_sec * 10 + *ret - '0';
        ++ret;
      }
      now = tv_sec;
#if !defined(_WIN32)
      ptm = localtime_r(&now, &tmBuf);
#else
      ptm = localtime(&now);
#endif
    } else
#endif
    {
      unsigned num = 0;
      while (isdigit(*e)) {
        num = num * 10 + *e - '0';
        ++e;
      }
      if (*e != 'q') {
        continue;
      }
      *cp = '\0';
      if (*f) {
        ret = ::strptime(ret, f, ptm);
        if (!ret) {
          break;
        }
      }
      unsigned long mul = NS_PER_SEC;
      if (num == 0) {
        num = INT_MAX;
      }
      tv_nsec = 0;
      while (isdigit(*ret) && num && (mul > 1)) {
        --num;
        mul /= 10;
        tv_nsec = tv_nsec + (*ret - '0') * mul;
        ++ret;
      }
    }
    f = cp = e;
    ++f;
  }

  if (ret) {
    tv_sec = mktime(ptm);
    return ret;
  }

// Upon error, place a known value into the class, the current time.
#ifdef __linux__
  *this = log_time(CLOCK_REALTIME);
#else
  time(&now);
  tv_sec = now;
  tv_nsec = 0;
#endif
  return ret;
}

LIBLOG_ABI_PRIVATE log_time log_time::operator-=(const timespec& T) {
  // No concept of negative time, clamp to EPOCH
  if (*this <= T) {
    return *this = EPOCH;
  }

  if (this->tv_nsec < (unsigned long int)T.tv_nsec) {
    --this->tv_sec;
    this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;
  } else {
    this->tv_nsec -= T.tv_nsec;
  }
  this->tv_sec -= T.tv_sec;

  return *this;
}

LIBLOG_ABI_PRIVATE log_time log_time::operator+=(const timespec& T) {
  this->tv_nsec += (unsigned long int)T.tv_nsec;
  if (this->tv_nsec >= NS_PER_SEC) {
    this->tv_nsec -= NS_PER_SEC;
    ++this->tv_sec;
  }
  this->tv_sec += T.tv_sec;

  return *this;
}

LIBLOG_ABI_PRIVATE log_time log_time::operator-=(const log_time& T) {
  // No concept of negative time, clamp to EPOCH
  if (*this <= T) {
    return *this = EPOCH;
  }

  if (this->tv_nsec < T.tv_nsec) {
    --this->tv_sec;
    this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;
  } else {
    this->tv_nsec -= T.tv_nsec;
  }
  this->tv_sec -= T.tv_sec;

  return *this;
}

LIBLOG_ABI_PRIVATE log_time log_time::operator+=(const log_time& T) {
  this->tv_nsec += T.tv_nsec;
  if (this->tv_nsec >= NS_PER_SEC) {
    this->tv_nsec -= NS_PER_SEC;
    ++this->tv_sec;
  }
  this->tv_sec += T.tv_sec;

  return *this;
}
