/* Copyright (c) 2022, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

// Time conversion to/from POSIX time_t and struct tm, with no support
// for time zones other than UTC

#include <openssl/posix_time.h>

#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <string.h>
#include <time.h>

#include "internal.h"

#define SECS_PER_HOUR (60 * 60)
#define SECS_PER_DAY (INT64_C(24) * SECS_PER_HOUR)


// Is a year/month/day combination valid, in the range from year 0000
// to 9999?
static int is_valid_date(int64_t year, int64_t month, int64_t day) {
  if (day < 1 || month < 1 || year < 0 || year > 9999) {
    return 0;
  }
  switch (month) {
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
      return day > 0 && day <= 31;
    case 4:
    case 6:
    case 9:
    case 11:
      return day > 0 && day <= 30;
    case 2:
      if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
        return day > 0 && day <= 29;
      } else {
        return day > 0 && day <= 28;
      }
    default:
      return 0;
  }
}

// Is a time valid? Leap seconds of 60 are not considered valid, as
// the POSIX time in seconds does not include them.
static int is_valid_time(int64_t hours, int64_t minutes, int64_t seconds) {
  if (hours < 0 || minutes < 0 || seconds < 0 || hours > 23 || minutes > 59 ||
      seconds > 59) {
    return 0;
  }
  return 1;
}

// 0000-01-01 00:00:00 UTC
#define MIN_POSIX_TIME INT64_C(-62167219200)
// 9999-12-31 23:59:59 UTC
#define MAX_POSIX_TIME INT64_C(253402300799)

// Is an int64 time within our expected range?
static int is_valid_posix_time(int64_t time) {
  return MIN_POSIX_TIME <= time && time <= MAX_POSIX_TIME;
}

// Inspired by algorithms presented in
// https://howardhinnant.github.io/date_algorithms.html
// (Public Domain)
static int posix_time_from_utc(int64_t year, int64_t month, int64_t day,
                               int64_t hours, int64_t minutes, int64_t seconds,
                               int64_t *out_time) {
  if (!is_valid_date(year, month, day) ||
      !is_valid_time(hours, minutes, seconds)) {
    return 0;
  }
  if (month <= 2) {
    year--;  // Start years on Mar 1, so leap days always finish a year.
  }
  // At this point year will be in the range -1 and 9999.
  assert(-1 <= year && year <= 9999);
  int64_t era = (year >= 0 ? year : year - 399) / 400;
  int64_t year_of_era = year - era * 400;
  int64_t day_of_year =
      (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1;
  int64_t day_of_era =
      year_of_era * 365 + year_of_era / 4 - year_of_era / 100 + day_of_year;
  int64_t posix_days = era * 146097 + day_of_era - 719468;
  *out_time = posix_days * SECS_PER_DAY + hours * SECS_PER_HOUR + minutes * 60 +
              seconds;
  return 1;
}

// Inspired by algorithms presented in
// https://howardhinnant.github.io/date_algorithms.html
// (Public Domain)
static int utc_from_posix_time(int64_t time, int *out_year, int *out_month,
                               int *out_day, int *out_hours, int *out_minutes,
                               int *out_seconds) {
  if (!is_valid_posix_time(time)) {
    return 0;
  }
  int64_t days = time / SECS_PER_DAY;
  int64_t leftover_seconds = time % SECS_PER_DAY;
  if (leftover_seconds < 0) {
    days--;
    leftover_seconds += SECS_PER_DAY;
  }
  days += 719468;  // Shift to starting epoch of Mar 1 0000.
  // At this point, days will be in the range -61 and 3652364.
  assert(-61 <= days && days <= 3652364);
  int64_t era = (days > 0 ? days : days - 146096) / 146097;
  int64_t day_of_era = days - era * 146097;
  int64_t year_of_era = (day_of_era - day_of_era / 1460 + day_of_era / 36524 -
                         day_of_era / 146096) /
                        365;
  *out_year = (int)(year_of_era + era * 400);  // Year starting on Mar 1.
  int64_t day_of_year =
      day_of_era - (365 * year_of_era + year_of_era / 4 - year_of_era / 100);
  int64_t month_of_year = (5 * day_of_year + 2) / 153;
  *out_month =
      (int)(month_of_year < 10 ? month_of_year + 3 : month_of_year - 9);
  if (*out_month <= 2) {
    (*out_year)++;  // Adjust year back to Jan 1 start of year.
  }
  *out_day = (int)(day_of_year - (153 * month_of_year + 2) / 5 + 1);
  *out_hours = (int)(leftover_seconds / SECS_PER_HOUR);
  leftover_seconds %= SECS_PER_HOUR;
  *out_minutes = (int)(leftover_seconds / 60);
  *out_seconds = (int)(leftover_seconds % 60);
  return 1;
}

int OPENSSL_tm_to_posix(const struct tm *tm, int64_t *out) {
  return posix_time_from_utc(tm->tm_year + INT64_C(1900),
                             tm->tm_mon + INT64_C(1), tm->tm_mday, tm->tm_hour,
                             tm->tm_min, tm->tm_sec, out);
}

int OPENSSL_posix_to_tm(int64_t time, struct tm *out_tm) {
  struct tm tmp_tm = {0};
  if (!utc_from_posix_time(time, &tmp_tm.tm_year, &tmp_tm.tm_mon,
                           &tmp_tm.tm_mday, &tmp_tm.tm_hour, &tmp_tm.tm_min,
                           &tmp_tm.tm_sec)) {
    return 0;
  }
  tmp_tm.tm_year -= 1900;
  tmp_tm.tm_mon -= 1;
  *out_tm = tmp_tm;

  return 1;
}

int OPENSSL_timegm(const struct tm *tm, time_t *out) {
  static_assert(
      sizeof(time_t) == sizeof(int32_t) || sizeof(time_t) == sizeof(int64_t),
      "time_t is broken");
  int64_t posix_time;
  if (!OPENSSL_tm_to_posix(tm, &posix_time)) {
    return 0;
  }
  if (sizeof(time_t) == sizeof(int32_t) &&
      (posix_time > INT32_MAX || posix_time < INT32_MIN)) {
    return 0;
  }
  *out = (time_t)posix_time;
  return 1;
}

struct tm *OPENSSL_gmtime(const time_t *time, struct tm *out_tm) {
  static_assert(
      sizeof(time_t) == sizeof(int32_t) || sizeof(time_t) == sizeof(int64_t),
      "time_t is broken");
  int64_t posix_time = *time;
  if (!OPENSSL_posix_to_tm(posix_time, out_tm)) {
    return NULL;
  }
  return out_tm;
}

int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, int64_t offset_sec) {
  int64_t posix_time;
  if (!OPENSSL_tm_to_posix(tm, &posix_time)) {
    return 0;
  }
  static_assert(INT_MAX <= INT64_MAX / SECS_PER_DAY,
                "day offset in seconds cannot overflow");
  static_assert(MAX_POSIX_TIME <= INT64_MAX - INT_MAX * SECS_PER_DAY,
                "addition cannot overflow");
  static_assert(MIN_POSIX_TIME >= INT64_MIN - INT_MIN * SECS_PER_DAY,
                "addition cannot underflow");
  posix_time += offset_day * SECS_PER_DAY;
  if (posix_time > 0 && offset_sec > INT64_MAX - posix_time) {
    return 0;
  }
  if (posix_time < 0 && offset_sec < INT64_MIN - posix_time) {
    return 0;
  }
  posix_time += offset_sec;

  if (!OPENSSL_posix_to_tm(posix_time, tm)) {
    return 0;
  }

  return 1;
}

int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from,
                        const struct tm *to) {
  int64_t time_to, time_from;
  if (!OPENSSL_tm_to_posix(to, &time_to) ||
      !OPENSSL_tm_to_posix(from, &time_from)) {
    return 0;
  }
  // Times are in range, so these calculations can not overflow.
  static_assert(SECS_PER_DAY <= INT_MAX, "seconds per day does not fit in int");
  static_assert((MAX_POSIX_TIME - MIN_POSIX_TIME) / SECS_PER_DAY <= INT_MAX,
                "range of valid POSIX times, in days, does not fit in int");
  int64_t timediff = time_to - time_from;
  int64_t daydiff = timediff / SECS_PER_DAY;
  timediff %= SECS_PER_DAY;
  *out_secs = (int)timediff;
  *out_days = (int)daydiff;
  return 1;
}
