/*
 * Copyright (C) 2009 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "core/platform/DateComponents.h"

#include <limits.h>
#include "wtf/ASCIICType.h"
#include "wtf/DateMath.h"
#include "wtf/MathExtras.h"
#include "wtf/text/WTFString.h"

using namespace std;

namespace WebCore {

// HTML5 specification defines minimum week of year is one.
const int DateComponents::minimumWeekNumber = 1;

// HTML5 specification defines maximum week of year is 53.
const int DateComponents::maximumWeekNumber = 53;

static const int maximumMonthInMaximumYear = 8; // This is September, since months are 0 based.
static const int maximumDayInMaximumMonth = 13;
static const int maximumWeekInMaximumYear = 37; // The week of 275760-09-13

static const int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

static bool isLeapYear(int year)
{
    if (year % 4)
        return false;
    if (!(year % 400))
        return true;
    if (!(year % 100))
        return false;
    return true;
}

// 'month' is 0-based.
static int maxDayOfMonth(int year, int month)
{
    if (month != 1) // February?
        return daysInMonth[month];
    return isLeapYear(year) ? 29 : 28;
}

// 'month' is 0-based.
static int dayOfWeek(int year, int month, int day)
{
    int shiftedMonth = month + 2;
    // 2:January, 3:Feburuary, 4:March, ...

    // Zeller's congruence
    if (shiftedMonth <= 3) {
        shiftedMonth += 12;
        year--;
    }
    // 4:March, ..., 14:January, 15:February

    int highYear = year / 100;
    int lowYear = year % 100;
    // We add 6 to make the result Sunday-origin.
    int result = (day + 13 * shiftedMonth / 5 + lowYear + lowYear / 4 + highYear / 4 + 5 * highYear + 6) % 7;
    return result;
}

int DateComponents::maxWeekNumberInYear() const
{
    int day = dayOfWeek(m_year, 0, 1); // January 1.
    return day == Thursday || (day == Wednesday && isLeapYear(m_year)) ? maximumWeekNumber : maximumWeekNumber - 1;
}

static unsigned countDigits(const String& src, unsigned start)
{
    unsigned index = start;
    for (; index < src.length(); ++index) {
        if (!isASCIIDigit(src[index]))
            break;
    }
    return index - start;
}

// Very strict integer parser. Do not allow leading or trailing whitespace unlike charactersToIntStrict().
static bool toInt(const String& src, unsigned parseStart, unsigned parseLength, int& out)
{
    if (parseStart + parseLength > src.length() || parseLength <= 0)
        return false;
    int value = 0;
    unsigned current = parseStart;
    unsigned end = current + parseLength;

    // We don't need to handle negative numbers for ISO 8601.
    for (; current < end; ++current) {
        if (!isASCIIDigit(src[current]))
            return false;
        int digit = src[current] - '0';
        if (value > (INT_MAX - digit) / 10) // Check for overflow.
            return false;
        value = value * 10 + digit;
    }
    out = value;
    return true;
}

bool DateComponents::parseYear(const String& src, unsigned start, unsigned& end)
{
    unsigned digitsLength = countDigits(src, start);
    // Needs at least 4 digits according to the standard.
    if (digitsLength < 4)
        return false;
    int year;
    if (!toInt(src, start, digitsLength, year))
        return false;
    if (year < minimumYear() || year > maximumYear())
        return false;
    m_year = year;
    end = start + digitsLength;
    return true;
}

static bool withinHTMLDateLimits(int year, int month)
{
    if (year < DateComponents::minimumYear())
        return false;
    if (year < DateComponents::maximumYear())
        return true;
    return month <= maximumMonthInMaximumYear;
}

static bool withinHTMLDateLimits(int year, int month, int monthDay)
{
    if (year < DateComponents::minimumYear())
        return false;
    if (year < DateComponents::maximumYear())
        return true;
    if (month < maximumMonthInMaximumYear)
        return true;
    return monthDay <= maximumDayInMaximumMonth;
}

static bool withinHTMLDateLimits(int year, int month, int monthDay, int hour, int minute, int second, int millisecond)
{
    if (year < DateComponents::minimumYear())
        return false;
    if (year < DateComponents::maximumYear())
        return true;
    if (month < maximumMonthInMaximumYear)
        return true;
    if (monthDay < maximumDayInMaximumMonth)
        return true;
    if (monthDay > maximumDayInMaximumMonth)
        return false;
    // (year, month, monthDay) = (maximumYear, maximumMonthInMaximumYear, maximumDayInMaximumMonth)
    return !hour && !minute && !second && !millisecond;
}

bool DateComponents::addDay(int dayDiff)
{
    ASSERT(m_monthDay);

    int day = m_monthDay + dayDiff;
    if (day > maxDayOfMonth(m_year, m_month)) {
        day = m_monthDay;
        int year = m_year;
        int month = m_month;
        int maxDay = maxDayOfMonth(year, month);
        for (; dayDiff > 0; --dayDiff) {
            ++day;
            if (day > maxDay) {
                day = 1;
                ++month;
                if (month >= 12) { // month is 0-origin.
                    month = 0;
                    ++year;
                }
                maxDay = maxDayOfMonth(year, month);
            }
        }
        if (!withinHTMLDateLimits(year, month, day))
            return false;
        m_year = year;
        m_month = month;
    } else if (day < 1) {
        int month = m_month;
        int year = m_year;
        day = m_monthDay;
        for (; dayDiff < 0; ++dayDiff) {
            --day;
            if (day < 1) {
                --month;
                if (month < 0) {
                    month = 11;
                    --year;
                }
                day = maxDayOfMonth(year, month);
            }
        }
        if (!withinHTMLDateLimits(year, month, day))
            return false;
        m_year = year;
        m_month = month;
    } else {
        if (!withinHTMLDateLimits(m_year, m_month, day))
            return false;
    }
    m_monthDay = day;
    return true;
}

bool DateComponents::addMinute(int minute)
{
    // This function is used to adjust timezone offset. So m_year, m_month,
    // m_monthDay have values between the lower and higher limits.
    ASSERT(withinHTMLDateLimits(m_year, m_month, m_monthDay));

    int carry;
    // minute can be negative or greater than 59.
    minute += m_minute;
    if (minute > 59) {
        carry = minute / 60;
        minute = minute % 60;
    } else if (minute < 0) {
        carry = (59 - minute) / 60;
        minute += carry * 60;
        carry = -carry;
        ASSERT(minute >= 0 && minute <= 59);
    } else {
        if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, minute, m_second, m_millisecond))
            return false;
        m_minute = minute;
        return true;
    }

    int hour = m_hour + carry;
    if (hour > 23) {
        carry = hour / 24;
        hour = hour % 24;
    } else if (hour < 0) {
        carry = (23 - hour) / 24;
        hour += carry * 24;
        carry = -carry;
        ASSERT(hour >= 0 && hour <= 23);
    } else {
        if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, hour, minute, m_second, m_millisecond))
            return false;
        m_minute = minute;
        m_hour = hour;
        return true;
    }
    if (!addDay(carry))
        return false;
    if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, hour, minute, m_second, m_millisecond))
        return false;
    m_minute = minute;
    m_hour = hour;
    return true;
}

// Parses a timezone part, and adjust year, month, monthDay, hour, minute, second, millisecond.
bool DateComponents::parseTimeZone(const String& src, unsigned start, unsigned& end)
{
    if (start >= src.length())
        return false;
    unsigned index = start;
    if (src[index] == 'Z') {
        end = index + 1;
        return true;
    }

    bool minus;
    if (src[index] == '+')
        minus = false;
    else if (src[index] == '-')
        minus = true;
    else
        return false;
    ++index;

    int hour;
    int minute;
    if (!toInt(src, index, 2, hour) || hour < 0 || hour > 23)
        return false;
    index += 2;

    if (index >= src.length() || src[index] != ':')
        return false;
    ++index;

    if (!toInt(src, index, 2, minute) || minute < 0 || minute > 59)
        return false;
    index += 2;

    if (minus) {
        hour = -hour;
        minute = -minute;
    }

    // Subtract the timezone offset.
    if (!addMinute(-(hour * 60 + minute)))
        return false;
    end = index;
    return true;
}

bool DateComponents::parseMonth(const String& src, unsigned start, unsigned& end)
{
    unsigned index;
    if (!parseYear(src, start, index))
        return false;
    if (index >= src.length() || src[index] != '-')
        return false;
    ++index;

    int month;
    if (!toInt(src, index, 2, month) || month < 1 || month > 12)
        return false;
    --month;
    if (!withinHTMLDateLimits(m_year, month))
        return false;
    m_month = month;
    end = index + 2;
    m_type = Month;
    return true;
}

bool DateComponents::parseDate(const String& src, unsigned start, unsigned& end)
{
    unsigned index;
    if (!parseMonth(src, start, index))
        return false;
    // '-' and 2-digits are needed.
    if (index + 2 >= src.length())
        return false;
    if (src[index] != '-')
        return false;
    ++index;

    int day;
    if (!toInt(src, index, 2, day) || day < 1 || day > maxDayOfMonth(m_year, m_month))
        return false;
    if (!withinHTMLDateLimits(m_year, m_month, day))
        return false;
    m_monthDay = day;
    end = index + 2;
    m_type = Date;
    return true;
}

bool DateComponents::parseWeek(const String& src, unsigned start, unsigned& end)
{
    unsigned index;
    if (!parseYear(src, start, index))
        return false;

    // 4 characters ('-' 'W' digit digit) are needed.
    if (index + 3 >= src.length())
        return false;
    if (src[index] != '-')
        return false;
    ++index;
    if (src[index] != 'W')
        return false;
    ++index;

    int week;
    if (!toInt(src, index, 2, week) || week < minimumWeekNumber || week > maxWeekNumberInYear())
        return false;
    if (m_year == maximumYear() && week > maximumWeekInMaximumYear)
        return false;
    m_week = week;
    end = index + 2;
    m_type = Week;
    return true;
}

bool DateComponents::parseTime(const String& src, unsigned start, unsigned& end)
{
    int hour;
    if (!toInt(src, start, 2, hour) || hour < 0 || hour > 23)
        return false;
    unsigned index = start + 2;
    if (index >= src.length())
        return false;
    if (src[index] != ':')
        return false;
    ++index;

    int minute;
    if (!toInt(src, index, 2, minute) || minute < 0 || minute > 59)
        return false;
    index += 2;

    int second = 0;
    int millisecond = 0;
    // Optional second part.
    // Do not return with false because the part is optional.
    if (index + 2 < src.length() && src[index] == ':') {
        if (toInt(src, index + 1, 2, second) && second >= 0 && second <= 59) {
            index += 3;

            // Optional fractional second part.
            if (index < src.length() && src[index] == '.') {
                unsigned digitsLength = countDigits(src, index + 1);
                if (digitsLength >  0) {
                    ++index;
                    bool ok;
                    if (digitsLength == 1) {
                        ok = toInt(src, index, 1, millisecond);
                        millisecond *= 100;
                    } else if (digitsLength == 2) {
                        ok = toInt(src, index, 2, millisecond);
                        millisecond *= 10;
                    } else { // digitsLength >= 3
                        ok = toInt(src, index, 3, millisecond);
                    }
                    ASSERT_UNUSED(ok, ok);
                    index += digitsLength;
                }
            }
        }
    }
    m_hour = hour;
    m_minute = minute;
    m_second = second;
    m_millisecond = millisecond;
    end = index;
    m_type = Time;
    return true;
}

bool DateComponents::parseDateTimeLocal(const String& src, unsigned start, unsigned& end)
{
    unsigned index;
    if (!parseDate(src, start, index))
        return false;
    if (index >= src.length())
        return false;
    if (src[index] != 'T')
        return false;
    ++index;
    if (!parseTime(src, index, end))
        return false;
    if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
        return false;
    m_type = DateTimeLocal;
    return true;
}

bool DateComponents::parseDateTime(const String& src, unsigned start, unsigned& end)
{
    unsigned index;
    if (!parseDate(src, start, index))
        return false;
    if (index >= src.length())
        return false;
    if (src[index] != 'T')
        return false;
    ++index;
    if (!parseTime(src, index, index))
        return false;
    if (!parseTimeZone(src, index, end))
        return false;
    if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
        return false;
    m_type = DateTime;
    return true;
}

static inline double positiveFmod(double value, double divider)
{
    double remainder = fmod(value, divider);
    return remainder < 0 ? remainder + divider : remainder;
}

void DateComponents::setMillisecondsSinceMidnightInternal(double msInDay)
{
    ASSERT(msInDay >= 0 && msInDay < msPerDay);
    m_millisecond = static_cast<int>(fmod(msInDay, msPerSecond));
    double value = floor(msInDay / msPerSecond);
    m_second = static_cast<int>(fmod(value, secondsPerMinute));
    value = floor(value / secondsPerMinute);
    m_minute = static_cast<int>(fmod(value, minutesPerHour));
    m_hour = static_cast<int>(value / minutesPerHour);
}

bool DateComponents::setMillisecondsSinceEpochForDateInternal(double ms)
{
    m_year = msToYear(ms);
    int yearDay = dayInYear(ms, m_year);
    m_month = monthFromDayInYear(yearDay, isLeapYear(m_year));
    m_monthDay = dayInMonthFromDayInYear(yearDay, isLeapYear(m_year));
    return true;
}

bool DateComponents::setMillisecondsSinceEpochForDate(double ms)
{
    m_type = Invalid;
    if (!std::isfinite(ms))
        return false;
    if (!setMillisecondsSinceEpochForDateInternal(round(ms)))
        return false;
    if (!withinHTMLDateLimits(m_year, m_month, m_monthDay))
        return false;
    m_type = Date;
    return true;
}

bool DateComponents::setMillisecondsSinceEpochForDateTime(double ms)
{
    m_type = Invalid;
    if (!std::isfinite(ms))
        return false;
    ms = round(ms);
    setMillisecondsSinceMidnightInternal(positiveFmod(ms, msPerDay));
    if (!setMillisecondsSinceEpochForDateInternal(ms))
        return false;
    if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
        return false;
    m_type = DateTime;
    return true;
}

bool DateComponents::setMillisecondsSinceEpochForDateTimeLocal(double ms)
{
    // Internal representation of DateTimeLocal is the same as DateTime except m_type.
    if (!setMillisecondsSinceEpochForDateTime(ms))
        return false;
    m_type = DateTimeLocal;
    return true;
}

bool DateComponents::setMillisecondsSinceEpochForMonth(double ms)
{
    m_type = Invalid;
    if (!std::isfinite(ms))
        return false;
    if (!setMillisecondsSinceEpochForDateInternal(round(ms)))
        return false;
    if (!withinHTMLDateLimits(m_year, m_month))
        return false;
    m_type = Month;
    return true;
}

bool DateComponents::setMillisecondsSinceMidnight(double ms)
{
    m_type = Invalid;
    if (!std::isfinite(ms))
        return false;
    setMillisecondsSinceMidnightInternal(positiveFmod(round(ms), msPerDay));
    m_type = Time;
    return true;
}

bool DateComponents::setMonthsSinceEpoch(double months)
{
    if (!std::isfinite(months))
        return false;
    months = round(months);
    double doubleMonth = positiveFmod(months, 12);
    double doubleYear = 1970 + (months - doubleMonth) / 12;
    if (doubleYear < minimumYear() || maximumYear() < doubleYear)
        return false;
    int year = static_cast<int>(doubleYear);
    int month = static_cast<int>(doubleMonth);
    if (!withinHTMLDateLimits(year, month))
        return false;
    m_year = year;
    m_month = month;
    m_type = Month;
    return true;
}

// Offset from January 1st to Monday of the ISO 8601's first week.
//   ex. If January 1st is Friday, such Monday is 3 days later. Returns 3.
static int offsetTo1stWeekStart(int year)
{
    int offsetTo1stWeekStart = 1 - dayOfWeek(year, 0, 1);
    if (offsetTo1stWeekStart <= -4)
        offsetTo1stWeekStart += 7;
    return offsetTo1stWeekStart;
}

bool DateComponents::setMillisecondsSinceEpochForWeek(double ms)
{
    m_type = Invalid;
    if (!std::isfinite(ms))
        return false;
    ms = round(ms);

    m_year = msToYear(ms);
    if (m_year < minimumYear() || m_year > maximumYear())
        return false;

    int yearDay = dayInYear(ms, m_year);
    int offset = offsetTo1stWeekStart(m_year);
    if (yearDay < offset) {
        // The day belongs to the last week of the previous year.
        m_year--;
        if (m_year <= minimumYear())
            return false;
        m_week = maxWeekNumberInYear();
    } else {
        m_week = ((yearDay - offset) / 7) + 1;
        if (m_week > maxWeekNumberInYear()) {
            m_year++;
            m_week = 1;
        }
        if (m_year > maximumYear() || (m_year == maximumYear() && m_week > maximumWeekInMaximumYear))
            return false;
    }
    m_type = Week;
    return true;
}

double DateComponents::millisecondsSinceEpochForTime() const
{
    ASSERT(m_type == Time || m_type == DateTime || m_type == DateTimeLocal);
    return ((m_hour * minutesPerHour + m_minute) * secondsPerMinute + m_second) * msPerSecond + m_millisecond;
}

double DateComponents::millisecondsSinceEpoch() const
{
    switch (m_type) {
    case Date:
        return dateToDaysFrom1970(m_year, m_month, m_monthDay) * msPerDay;
    case DateTime:
    case DateTimeLocal:
        return dateToDaysFrom1970(m_year, m_month, m_monthDay) * msPerDay + millisecondsSinceEpochForTime();
    case Month:
        return dateToDaysFrom1970(m_year, m_month, 1) * msPerDay;
    case Time:
        return millisecondsSinceEpochForTime();
    case Week:
        return (dateToDaysFrom1970(m_year, 0, 1) + offsetTo1stWeekStart(m_year) + (m_week - 1) * 7) * msPerDay;
    case Invalid:
        break;
    }
    ASSERT_NOT_REACHED();
    return invalidMilliseconds();
}

double DateComponents::monthsSinceEpoch() const
{
    ASSERT(m_type == Month);
    return (m_year - 1970) * 12 + m_month;
}

String DateComponents::toStringForTime(SecondFormat format) const
{
    ASSERT(m_type == DateTime || m_type == DateTimeLocal || m_type == Time);
    SecondFormat effectiveFormat = format;
    if (m_millisecond)
        effectiveFormat = Millisecond;
    else if (format == None && m_second)
        effectiveFormat = Second;

    switch (effectiveFormat) {
    default:
        ASSERT_NOT_REACHED();
        // Fallback to None.
    case None:
        return String::format("%02d:%02d", m_hour, m_minute);
    case Second:
        return String::format("%02d:%02d:%02d", m_hour, m_minute, m_second);
    case Millisecond:
        return String::format("%02d:%02d:%02d.%03d", m_hour, m_minute, m_second, m_millisecond);
    }
}

String DateComponents::toString(SecondFormat format) const
{
    switch (m_type) {
    case Date:
        return String::format("%04d-%02d-%02d", m_year, m_month + 1, m_monthDay);
    case DateTime:
        return String::format("%04d-%02d-%02dT", m_year, m_month + 1, m_monthDay)
            + toStringForTime(format) + String("Z");
    case DateTimeLocal:
        return String::format("%04d-%02d-%02dT", m_year, m_month + 1, m_monthDay)
            + toStringForTime(format);
    case Month:
        return String::format("%04d-%02d", m_year, m_month + 1);
    case Time:
        return toStringForTime(format);
    case Week:
        return String::format("%04d-W%02d", m_year, m_week);
    case Invalid:
        break;
    }
    ASSERT_NOT_REACHED();
    return String("(Invalid DateComponents)");
}

} // namespace WebCore
