// Copyright 2016 The Fuchsia Authors
//
// 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 <ctime>

#include "util/datetime_util.h"

namespace cobalt {
namespace util {

namespace {

// The algorithm in this file was copied from
// http://howardhinnant.github.io/date_algorithms.html
// See that site for further explanation.

// Recall that a year is a leap year if it is a multiple of 4 that is not
// a multiple of 100 unless it is a multiple of 400. Thus the pattern of
// leap years is periodic with period 400 years.

// There are 146097 days in every 400 year era:
// 146097 = 365 * 400 + 100 - 3. Of the integers in the range [0, 399]
// there are 100 multiples of 4 but 3 of those are multiples of 100
// and not multiples of 400, namely 100, 200 and 300.
static const uint32_t kNumDaysPerEra = 146097;

// The algorithm below uses an epoch of March 1, year 0
// whereas our API uses an epoch of January 1, 1970.
// kEpochOffset is the number of days from 0-3-1 to 1970-1-1
// proof:
// The number of days from 0-3-1 to 2000-3-1 is 5*kNumDaysPerEra
// The number of days from 1970-3-1 to 2000-3-1 is 30*365 + 8
// because the following years were leap years: '72 '76 '80 '84 '88 '92 '96 2000
// The number of days from 1970-1-1 to 1970-3-1 is 59.
static const uint32_t kEpochOffset =
    kNumDaysPerEra * 5L - 30L * 365L - 8L - 59L;

typedef struct tm TimeInfo;

CalendarDate TimeInfoToCalendarDate(const TimeInfo& time_info) {
  CalendarDate calendar_date;
  calendar_date.day_of_month = time_info.tm_mday;
  calendar_date.month = time_info.tm_mon + 1;
  calendar_date.year = time_info.tm_year + 1900;
  return calendar_date;
}

}  // namespace

uint32_t TimeToDayIndex(time_t time, Metric::TimeZonePolicy time_zone) {
  TimeInfo time_info;
  switch (time_zone) {
    case Metric::LOCAL:
      localtime_r(&time, &time_info);
      break;
    case Metric::UTC:
      gmtime_r(&time, &time_info);
      break;
    default:
      return UINT32_MAX;
  }
  return CalendarDateToDayIndex(TimeInfoToCalendarDate(time_info));
}

uint32_t CalendarDateToDayIndex(const CalendarDate& calendar_date) {
  // This implementation was copied from
  // http://howardhinnant.github.io/date_algorithms.html#days_from_civil.
  // This same code is also used in the function DayOrdinal() in
  // Google's civil_time.cc.
  //
  // There is an ostensibly simpler but less portable solution to this
  // problem presented in CalendarDateToDayIndexAltImpl() in
  // datetime_util_test.cc.

  if (calendar_date.year < 1970 || calendar_date.year >= 10000 ||
      calendar_date.month < 1 || calendar_date.month > 12 ||
      calendar_date.day_of_month < 1 || calendar_date.day_of_month > 31) {
    return kInvalidIndex;
  }

  // This algorithm counts years as beginning on March 1. Convert to that now.
  // This trick has the advantage that a leap day is the last day of the year.
  const uint32_t year = calendar_date.year - (calendar_date.month <= 2 ? 1 : 0);

  // Which 400-year era is it?
  const uint32_t era = year / 400;

  // The year of the era is the year mod 400.
  const uint32_t yoe = year - era * 400;

  // Now we compute the day of the year, where March 1 is day number 1.
  // The main idea is the following trick which uses integer division to
  // capture the set of months that have 30 instead of 31 days. Let n be a month
  // number where n = 1 means March, n = 2 means April, etc. Notice that
  // For n = 1...10, using integer division,  we have that
  // (3n+2)/5 = 1, 1, 2, 2, 3, 4, 4, 5, 5, 6. It follows that the expression
  // (153*n + 2)/5 yields the number of days from March 1 through the end
  // of month number n. To see this note that (153*n + 2)/5 = 30n + (3n+2)/5.
  // Plugging in to the formula we have
  // n=1 (March)  -> 30 +   1
  // n=2 (April)  -> 30*2 + 1
  // n=3 (May)    -> 30*3 + 2
  // n=4 (June)   -> 30*4 + 2
  // n=5 (July)   -> 30*5 + 3
  // n=6 (August) -> 30*6 + 4
  // etc.
  const uint32_t doy =
      (153 * (calendar_date.month + (calendar_date.month > 2 ? -3 : 9)) + 2) /
          5 +
      calendar_date.day_of_month - 1;

  // Now we compute the day of the era. This is relatively easy using
  // the formula for leap years described at the top of this file.
  const int doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;

  // shift epoch from 0-03-01 to 1970-01-01
  return era * kNumDaysPerEra + doe - kEpochOffset;
}

time_t MidnightUtcFromDayIndex(uint32_t day_index) {
  return day_index * kNumUnixSecondsPerDay;
}

CalendarDate DayIndexToCalendarDate(uint32_t day_index) {
  // This function is an inverse to CalendarDateToDayIndex.
  // But because gmtime_r is a standard function unlike timegm, we
  // use the more straightforward implementation in this direction.
  time_t unix_time = day_index * kNumUnixSecondsPerDay;
  TimeInfo time_info;
  gmtime_r(&unix_time, &time_info);
  return TimeInfoToCalendarDate(time_info);
}

uint32_t DayIndexToWeekIndex(uint32_t day_index) {
  // Day zero was a Thursday which is 4 days after Sunday.
  return (day_index + 4) / 7;
}

uint32_t CalendarDateToWeekIndex(const CalendarDate& calendar_date) {
  return DayIndexToWeekIndex(CalendarDateToDayIndex(calendar_date));
}

CalendarDate WeekIndexToCalendarDate(uint32_t week_index) {
  // Day zero was a Thursday which is 4 days after Sunday.
  return DayIndexToCalendarDate(week_index * 7 - (week_index > 0 ? 4 : 0));
}

uint32_t DayIndexToMonthIndex(uint32_t day_index) {
  return CalendarDateToMonthIndex(DayIndexToCalendarDate(day_index));
}

uint32_t CalendarDateToMonthIndex(const CalendarDate& calendar_date) {
  if (calendar_date.year < 1970 || calendar_date.month < 1 ||
      calendar_date.month > 12) {
    return UINT32_MAX;
  }
  return 12 * (calendar_date.year - 1970) + calendar_date.month - 1;
}

CalendarDate MonthIndexToCalendarDate(uint32_t month_index) {
  CalendarDate calendar_date;
  calendar_date.day_of_month = 1;
  calendar_date.month = (month_index % 12) + 1;
  calendar_date.year = month_index / 12 + 1970;
  return calendar_date;
}

// Returns the the given time as a number of seconds since the Unix epoch.
int64_t ToUnixSeconds(std::chrono::system_clock::time_point t) {
  return (std::chrono::duration_cast<std::chrono::seconds>(
              t.time_since_epoch()))
      .count();
}

// Returns the given number of seconds since the Unix epoch as a time_point.
std::chrono::system_clock::time_point FromUnixSeconds(int64_t seconds) {
  return std::chrono::system_clock::time_point(
      std::chrono::system_clock::duration(std::chrono::seconds(seconds)));
}

}  // namespace util
}  // namespace cobalt
