/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, 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.
 */

/**
 *    @file
 *      Various utility functions for dealing with time and dates.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <limits>
#include <stdint.h>
#include <type_traits>

#include <lib/core/CHIPCore.h>
#include <lib/support/SafeInt.h>

#include "TimeUtils.h"

namespace chip {

enum
{
    // Number of days during the invariant part of the year (after the leap day).
    kDaysFromMarch1ToDecember31 = 306,

    // Number of years in a Gregorian "cycle", where a cycle is the 400-year period
    // over which the Gregorian calendar repeats.
    kYearsPerCycle = 400,

    // Total number of days within cycle.
    kDaysPerCycle = 146097,

    // Total number of days between 0000/03/01 and 1970/01/01.
    kEpochOffsetDays = 719468
};

/* Returns the number of days between January 1st and March 1st for a given year.
 */
static inline uint8_t DaysToMarch1(uint16_t year)
{
    if (IsLeapYear(year))
        return 60;
    return 59;
}

/* Converts a March-based month number (0=March, 1=April, etc.) to a March-1st based day of year (0=March 1st, 1=March 2nd, etc.).
 *
 * NOTE: This is based on the math described in http://howardhinnant.github.io/date_algorithms.html.
 */
static uint16_t MarchBasedMonthToDayOfYear(uint8_t month)
{
    return static_cast<uint16_t>((153 * month + 2) / 5);
}

/* Converts a March-1st based day of year (0=March 1st, 1=March 2nd, etc.) to a March-based month number (0=March, 1=April, etc.).
 */
static uint8_t MarchBasedDayOfYearToMonth(uint16_t dayOfYear)
{
    // This assumes dayOfYear is not using the full uint16_t range, so the cast
    // to uint8_t doesn't overflow.
    return static_cast<uint8_t>((5 * dayOfYear + 2) / 153);
}

/**
 *  @def IsLeapYear
 *
 *  @brief
 *    Returns true if the given year is a leap year according to the Gregorian calendar.
 *
 *  @param year
 *    Gregorian calendar year.
 *
 */
bool IsLeapYear(uint16_t year)
{
    return (year % kLeapYearInterval) == 0 && ((year % kYearsPerCentury) != 0 || (year % kYearsPerCycle) == 0);
}

/**
 *  @def DaysInMonth
 *
 *  @brief
 *    Returns the number of days in the given month/year.
 *
 *  @param year
 *    Gregorian calendar year.
 *
 *  @param month
 *    Month in standard form (1=January ... 12=December).
 *
 *  @return
 *    Number of days in the given month.
 */
uint8_t DaysInMonth(uint16_t year, uint8_t month)
{
    static const uint8_t daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

    if (month == kFebruary && IsLeapYear(year))
        return 29;
    if (month >= kJanuary && month <= kDecember)
        return daysInMonth[month - 1];
    return 0;
}

/**
 *  @def FirstWeekdayOfYear
 *
 *  @brief
 *    Returns the day of the week for January 1st of the given year.
 *
 *  @param year
 *    Gregorian calendar year.
 *
 *  @return
 *    The day-of-week (0=Sunday...6=Saturday).
 */
uint8_t FirstWeekdayOfYear(uint16_t year)
{
    // Compute the day of the week for the first day of the given year using Gauss' algorithm.
    return static_cast<uint8_t>(
        (1 + 5 * ((year - 1) % kLeapYearInterval) + 4 * ((year - 1) % kYearsPerCentury) + 6 * ((year - 1) % kYearsPerCycle)) %
        kDaysPerWeek);
}

/**
 *  @def OrdinalDateToCalendarDate
 *
 *  @brief
 *    Convert an ordinal date (year/day-of-year) to a calendar date.
 *
 *  @param year
 *    Gregorian calendar year.
 *
 *  @param dayOfYear
 *    Ordinal day of year, base 1 (1=January 1st, 2=January 2nd, etc.).
 *
 *  @param month
 *    [OUTPUT] Corresponding month in standard form (1=January ... 12=December).
 *
 *  @param dayOfMonth
 *    [OUTPUT] Corresponding day-of-month in standard form (1=1st, 2=2nd, etc.).
 *
 */
void OrdinalDateToCalendarDate(uint16_t year, uint16_t dayOfYear, uint8_t & month, uint8_t & dayOfMonth)
{
    uint8_t daysToMarch1 = DaysToMarch1(year);

    // Make dayOfYear base 0.
    dayOfYear = static_cast<uint16_t>(dayOfYear - 1);

    // Adjust dayOfYear to a March 1st base (i.e. 0 = March 1, 1 = March 2, etc.).  This numbers January
    // and February at the end of the range, with the benefit that day numbering is identical between
    // standard and leap years with the exception of the leap day itself.
    if (dayOfYear < daysToMarch1)
        dayOfYear = static_cast<uint16_t>(dayOfYear + kDaysFromMarch1ToDecember31);
    else
        dayOfYear = static_cast<uint16_t>(dayOfYear - daysToMarch1);

    // Compute a March-based month number (i.e. 0=March...11=February) from the day of year.  This is based
    // on the logic in http://howardhinnant.github.io/date_algorithms.html.
    month = MarchBasedDayOfYearToMonth(dayOfYear);

    // Compute the days from March 1st to the start of the corresponding month.
    uint16_t daysFromMarch1ToStartOfMonth = MarchBasedMonthToDayOfYear(month);

    // Compute the day of month in standard form (1=1st, 2=2nd, etc.).
    dayOfMonth = static_cast<uint8_t>(dayOfYear - daysFromMarch1ToStartOfMonth + 1);

    // Convert the month number to standard form (1=January...12=December).
    month = static_cast<uint8_t>(month + (month < 10 ? 3 : -9));
}

/**
 *  @def CalendarDateToOrdinalDate
 *
 *  @brief
 *    Convert an calendar date to ordinal form (year/day-of-year).
 *
 *  @param year
 *    Gregorian calendar year.
 *
 *  @param month
 *    Month in standard form (1=January ... 12=December).
 *
 *  @param dayOfMonth
 *    Day-of-month in standard form (1=1st, 2=2nd, etc.).
 *
 *  @param dayOfYear
 *    [OUTPUT] Ordinal day of year, base 1 (1=January 1st, 2=January 2nd, etc.).
 *
 */
void CalendarDateToOrdinalDate(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint16_t & dayOfYear)
{
    // Convert month to a March-based month number (i.e. 0=March, 1=April, ...11=February).
    month = static_cast<uint8_t>(month + (month > kFebruary ? -3 : 9));

    // Compute the days from March 1st to the start of the corresponding month.
    dayOfYear = MarchBasedMonthToDayOfYear(month);

    // Adjust dayOfYear to be January-based (0=January 1st, 1=January 2nd...).
    if (dayOfYear < kDaysFromMarch1ToDecember31)
        dayOfYear = static_cast<uint16_t>(dayOfYear + DaysToMarch1(year));
    else
        dayOfYear = static_cast<uint16_t>(dayOfYear - kDaysFromMarch1ToDecember31);

    // Add in day of month, converting to base 1 in the process.
    dayOfYear = static_cast<uint16_t>(dayOfYear + dayOfMonth);
}

/**
 *  @def CalendarDateToDaysSinceUnixEpoch
 *
 *  @brief
 *    Convert a calendar date to the number of days since 1970-01-01.
 *
 *  @param year
 *    Gregorian calendar year in the range 1970 to 28276.
 *
 *  @param month
 *    Month in standard form (1=January ... 12=December).
 *
 *  @param dayOfMonth
 *    Day-of-month in standard form (1=1st, 2=2nd, etc.).
 *
 *  @param daysSinceEpoch
 *    [OUTPUT] Number of days since 1970-01-01.
 *
 *  @return
 *    True if the date was converted successfully.  False if the given year falls outside the
 *    representable range.
 *
 *  @note
 *    This function makes no attempt to verify the correct range of any arguments other than year.
 *    Therefore callers must make sure the supplied values are valid prior to calling the function.
 */
bool CalendarDateToDaysSinceUnixEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint32_t & daysSinceEpoch)
{
    // NOTE: This algorithm is based on the logic described in http://howardhinnant.github.io/date_algorithms.html.

    // Return immediately if the year is out of range.
    if (year < kUnixEpochYear || year > kMaxYearInDaysSinceUnixEpoch32)
    {
        daysSinceEpoch = UINT32_MAX;
        return false;
    }

    // Adjust the year and month to be March-based (i.e. 0=March, 1=April, ...11=February).
    if (month <= kFebruary)
    {
        year--;
        month = static_cast<uint8_t>(month + 9);
    }
    else
        month = static_cast<uint8_t>(month - 3);

    // Compute the days from March 1st to the start of the specified day.
    uint16_t dayOfYear = static_cast<uint16_t>(MarchBasedMonthToDayOfYear(month) + (dayOfMonth - 1));

    // Compute the 400-year Gregorian "cycle" within which the given year falls.
    uint16_t cycle = static_cast<uint16_t>(year / kYearsPerCycle);

    // Compute the relative year within the cycle.
    uint32_t yearOfCycle = year - (cycle * kYearsPerCycle);

    // Compute the relative day within the cycle, accounting for leap-years.
    uint32_t dayOfCycle =
        (yearOfCycle * kDaysPerStandardYear) + dayOfYear - (yearOfCycle / kYearsPerCentury) + (yearOfCycle / kLeapYearInterval);

    // Compute the total number of days since the start of the logical calendar (0000-03-01).
    uint32_t daysSinceCalendarStart = (cycle * kDaysPerCycle) + dayOfCycle;

    // Adjust the days value to be days since 1970-01-01.
    daysSinceEpoch = daysSinceCalendarStart - kEpochOffsetDays;

    return true;
}

/**
 *  @def DaysSinceUnixEpochToCalendarDate
 *
 *  @brief
 *    Convert the number of days since 1970-01-01 to a calendar date.
 *
 *  @param daysSinceEpoch
 *    Number of days since 1970-01-01.
 *
 *  @param year
 *    [OUTPUT] Gregorian calendar year.
 *
 *  @param month
 *    [OUTPUT] Month in standard form (1=January ... 12=December).
 *
 *  @param dayOfMonth
 *    [OUTPUT] Day-of-month in standard form (1=1st, 2=2nd, etc.).
 *
 *  @return
 *     True if the conversion was successful.  False if the year would not fit
 *     in uint16_t.
 */
bool DaysSinceUnixEpochToCalendarDate(uint32_t daysSinceEpoch, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth)
{
    // NOTE: This algorithm is based on the logic described in http://howardhinnant.github.io/date_algorithms.html.
    if (daysSinceEpoch / kDaysPerStandardYear + 1 > std::numeric_limits<std::remove_reference<decltype(year)>::type>::max())
    {
        // Our year calculation will likely overflow.
        return false;
    }

    // Adjust days value to be relative to 0000-03-01.
    daysSinceEpoch += kEpochOffsetDays;

    // Compute the 400-year Gregorian cycle in which the given day resides.
    uint32_t cycle = daysSinceEpoch / kDaysPerCycle;

    // Compute the relative day within the cycle.
    uint32_t dayOfCycle = daysSinceEpoch - (cycle * kDaysPerCycle);

    // Compute the relative year within the cycle, adjusting for leap-years.
    uint16_t yearOfCycle =
        static_cast<uint16_t>((dayOfCycle - dayOfCycle / 1460 + dayOfCycle / 36524 - dayOfCycle / 146096) / kDaysPerStandardYear);

    // Compute the relative day with the year.
    uint16_t dayOfYear = static_cast<uint16_t>(
        dayOfCycle - (yearOfCycle * kDaysPerStandardYear + yearOfCycle / kLeapYearInterval - yearOfCycle / kYearsPerCentury));

    // Compute a March-based month number (i.e. 0=March...11=February) from the day of year.
    month = MarchBasedDayOfYearToMonth(dayOfYear);

    // Compute the days from March 1st to the start of the corresponding month.
    uint16_t daysFromMarch1ToStartOfMonth = MarchBasedMonthToDayOfYear(month);

    // Compute the day of month in standard form (1=1st, 2=2nd, etc.).
    dayOfMonth = static_cast<uint8_t>(dayOfYear - daysFromMarch1ToStartOfMonth + 1);

    // Convert the month number to standard form (1=January...12=December).
    month = static_cast<uint8_t>(month + (month < 10 ? 3 : -9));

    // Compute the year, adjusting for the standard start of year (January).
    year = static_cast<uint16_t>(yearOfCycle + cycle * kYearsPerCycle);
    if (month <= kFebruary)
        year++;
    return true;
}

/**
 *  @def AdjustCalendarDate
 *
 *  @brief
 *    Adjust a calendar date by a given number of days (positive or negative).
 *
 *  @param year
 *    [INPUT/OUTPUT] Gregorian calendar year.
 *
 *  @param month
 *    [INPUT/OUTPUT] Month in standard form (1=January ... 12=December).
 *
 *  @param dayOfMonth
 *    [INPUT/OUTPUT] Day-of-month in standard form (1=1st, 2=2nd, etc.).
 *
 *  @param relativeDays
 *    Number of days to add/subtract from given calendar date.
 *
 *  @return
 *    True if the adjustment succeeded.  False if the adjustment would put us
 *    outside the representable date range.
 *
 *  @note
 *    Given date must be equal to or greater than 1970-01-01.
 */
bool AdjustCalendarDate(uint16_t & year, uint8_t & month, uint8_t & dayOfMonth, int32_t relativeDays)
{
    uint32_t daysSinceEpoch;
    if (!CalendarDateToDaysSinceUnixEpoch(year, month, dayOfMonth, daysSinceEpoch))
    {
        return false;
    }

    // Make sure we can do our additions without overflowing.
    int64_t adjustedDays = static_cast<int64_t>(daysSinceEpoch) + relativeDays;
    if (!CanCastTo<uint32_t>(adjustedDays))
    {
        return false;
    }

    return DaysSinceUnixEpochToCalendarDate(static_cast<uint32_t>(adjustedDays), year, month, dayOfMonth);
}

/**
 *  @def CalendarTimeToSecondsSinceUnixEpoch
 *
 *  @brief
 *    Convert a calendar date and time to the number of seconds since 1970-01-01 00:00:00 UTC.
 *
 *  @details
 *    This function is roughly equivalent to the POSIX gmtime() function with the exception
 *    that the output time value is limited to positive values up to 2^32-1.  This limits the
 *    representable date range to the year 2105.
 *
 *  @note
 *    This function makes no attempt to verify the correct range of any arguments other than year.
 *    Therefore callers must make sure the supplied values are valid prior to invocation.
 *
 *  @param secondsSinceEpoch
 *    Number of seconds since 1970-01-01 00:00:00 UTC.  Note: this value is compatible with
 *    *positive* values of the POSIX time_t value up to the year 2105.
 *
 *  @param year
 *    Gregorian calendar year in the range 1970 to 2105.
 *
 *  @param month
 *    Month in standard form (1=January ... 12=December).
 *
 *  @param dayOfMonth
 *    Day-of-month in standard form (1=1st, 2=2nd, etc.).
 *
 *  @param hour
 *    Hour (0-23).
 *
 *  @param minute
 *    Minute (0-59).
 *
 *  @param second
 *    Second (0-59).
 *
 *  @return
 *    True if the date/time was converted successfully.  False if the given year falls outside the
 *    representable range.
 */
bool CalendarTimeToSecondsSinceUnixEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint8_t hour, uint8_t minute,
                                         uint8_t second, uint32_t & secondsSinceEpoch)
{
    uint32_t daysSinceEpoch;

    // Return immediately if the year is out of range.
    if (year < kUnixEpochYear || year > kMaxYearInSecondsSinceUnixEpoch32)
    {
        secondsSinceEpoch = UINT32_MAX;
        return false;
    }

    CalendarDateToDaysSinceUnixEpoch(year, month, dayOfMonth, daysSinceEpoch);

    secondsSinceEpoch = (daysSinceEpoch * kSecondsPerDay) + (hour * kSecondsPerHour) + (minute * kSecondsPerMinute) + second;

    return true;
}
/**
 *  @brief
 *    Convert the number of seconds since 1970-01-01 00:00:00 UTC to a calendar date and time.
 *
 *  @note
 *    If secondsSinceEpoch is large enough this function will generate bad result. The way it is
 *    used in this file the generated result should be valid. Specifically, the largest
 *    possible value of secondsSinceEpoch input is (UINT32_MAX + kChipEpochSecondsSinceUnixEpoch),
 *    when it is called from ChipEpochToCalendarTime().
 */
static void SecondsSinceUnixEpochToCalendarTime(uint64_t secondsSinceEpoch, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth,
                                                uint8_t & hour, uint8_t & minute, uint8_t & second)
{
    uint32_t daysSinceEpoch = static_cast<uint32_t>(secondsSinceEpoch / kSecondsPerDay);
    static_assert((static_cast<uint64_t>(UINT32_MAX) + kChipEpochSecondsSinceUnixEpoch) / kSecondsPerDay <=
                      std::numeric_limits<decltype(daysSinceEpoch)>::max(),
                  "daysSinceEpoch would overflow");
    uint32_t timeOfDay = static_cast<uint32_t>(secondsSinceEpoch - (daysSinceEpoch * kSecondsPerDay));

    // Note: This call to DaysSinceUnixEpochToCalendarDate can't fail, because we
    // can't overflow a uint16_t year with a muximum possible value of the
    // secondsSinceEpoch input.
    static_assert((static_cast<uint64_t>(UINT32_MAX) + kChipEpochSecondsSinceUnixEpoch) / (kDaysPerStandardYear * kSecondsPerDay) +
                          1 <=
                      std::numeric_limits<std::remove_reference<decltype(year)>::type>::max(),
                  "What happened to our year or day lengths?");
    DaysSinceUnixEpochToCalendarDate(daysSinceEpoch, year, month, dayOfMonth);

    hour = static_cast<uint8_t>(timeOfDay / kSecondsPerHour);
    timeOfDay -= (hour * kSecondsPerHour);
    minute = static_cast<uint8_t>(timeOfDay / kSecondsPerMinute);
    timeOfDay -= (minute * kSecondsPerMinute);
    second = static_cast<uint8_t>(timeOfDay);
}

/**
 *  @def SecondsSinceUnixEpochToCalendarTime
 *
 *  @brief
 *    Convert the number of seconds since 1970-01-01 00:00:00 UTC to a calendar date and time.
 *
 *  @details
 *    This function is roughly equivalent to the POSIX mktime() function, with the following
 *    exceptions:
 *
 *    - Input time values are limited to positive values up to 2^32-1.  This limits the
 *    representable date range to the year 2105.
 *
 *    - The output time is always UTC (unlike mktime() which outputs time in the process's
 *    configured timezone).
 *
 *  @param secondsSinceEpoch
 *    Number of seconds since 1970-01-01 00:00:00 UTC.  Note: this value is compatible with
 *    *positive* values of the POSIX time_t value up to the year 2105.
 *
 *  @param year
 *    [OUTPUT] Gregorian calendar year.
 *
 *  @param month
 *    [OUTPUT] Month in standard form (1=January ... 12=December).
 *
 *  @param dayOfMonth
 *    [OUTPUT] Day-of-month in standard form (1=1st, 2=2nd, etc.).
 *
 *  @param hour
 *    [OUTPUT] Hour (0-23).
 *
 *  @param minute
 *    [OUTPUT] Minute (0-59).
 *
 *  @param second
 *    [OUTPUT] Second (0-59).
 */
void SecondsSinceUnixEpochToCalendarTime(uint32_t secondsSinceEpoch, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth,
                                         uint8_t & hour, uint8_t & minute, uint8_t & second)
{
    SecondsSinceUnixEpochToCalendarTime(static_cast<uint64_t>(secondsSinceEpoch), year, month, dayOfMonth, hour, minute, second);
}

bool CalendarToChipEpochTime(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint8_t hour, uint8_t minute, uint8_t second,
                             uint32_t & chipEpochTime)
{
    VerifyOrReturnError(year >= kChipEpochBaseYear && year <= kChipEpochMaxYear, false);

    uint32_t daysSinceUnixEpoch;
    CalendarDateToDaysSinceUnixEpoch(year, month, dayOfMonth, daysSinceUnixEpoch);

    chipEpochTime = ((daysSinceUnixEpoch - kChipEpochDaysSinceUnixEpoch) * kSecondsPerDay) + (hour * kSecondsPerHour) +
        (minute * kSecondsPerMinute) + second;

    return true;
}

void ChipEpochToCalendarTime(uint32_t chipEpochTime, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth, uint8_t & hour,
                             uint8_t & minute, uint8_t & second)
{
    SecondsSinceUnixEpochToCalendarTime(static_cast<uint64_t>(chipEpochTime) + kChipEpochSecondsSinceUnixEpoch, year, month,
                                        dayOfMonth, hour, minute, second);
}

bool UnixEpochToChipEpochTime(uint32_t unixEpochTime, uint32_t & chipEpochTime)
{
    VerifyOrReturnError(unixEpochTime >= kChipEpochSecondsSinceUnixEpoch, false);

    chipEpochTime = unixEpochTime - kChipEpochSecondsSinceUnixEpoch;

    return true;
}

} // namespace chip
