/*
 * 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 "DateComponents.h"

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

using namespace std;

namespace WebCore {

// The oldest day of Gregorian Calendar is 1582-10-15. We don't support dates older than it.
static const int gregorianStartYear = 1582;
static const int gregorianStartMonth = 9; // This is October, since months are 0 based.
static const int gregorianStartDay = 15;

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)) ? 53 : 52;
}

static unsigned countDigits(const UChar* src, unsigned length, unsigned start)
{
    unsigned index = start;
    for (; index < 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 UChar* src, unsigned length, unsigned parseStart, unsigned parseLength, int& out)
{
    if (parseStart + parseLength > length || parseLength <= 0)
        return false;
    int value = 0;
    const UChar* current = src + parseStart;
    const UChar* end = current + parseLength;

    // We don't need to handle negative numbers for ISO 8601.
    for (; current < end; ++current) {
        if (!isASCIIDigit(*current))
            return false;
        int digit = *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 UChar* src, unsigned length, unsigned start, unsigned& end)
{
    unsigned digitsLength = countDigits(src, length, start);
    // Needs at least 4 digits according to the standard.
    if (digitsLength < 4)
        return false;
    int year;
    if (!toInt(src, length, start, digitsLength, year))
        return false;
    // No support for years before Gregorian calendar.
    if (year < gregorianStartYear)
        return false;
    m_year = year;
    end = start + digitsLength;
    return true;
}

static bool beforeGregorianStartDate(int year, int month, int monthDay)
{
    return year < gregorianStartYear
        || (year == gregorianStartYear && month < gregorianStartMonth)
        || (year == gregorianStartYear && month == gregorianStartMonth && monthDay < gregorianStartDay);
}

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;
                    if (year < 0) // Check for overflow.
                        return false;
                }
                maxDay = maxDayOfMonth(year, month);
            }
        }
        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 (beforeGregorianStartDate(year, month, day))
                return false;
        }
        m_year = year;
        m_month = month;
    }
    m_monthDay = day;
    return true;
}

bool DateComponents::addMinute(int minute)
{
    int carry;
    // min can be negative or greater than 59.
    minute += m_minute;
    if (minute > 59) {
        carry = minute / 60;
        minute = minute % 60;
    } else if (m_minute < 0) {
        carry = (59 - m_minute) / 60;
        minute += carry * 60;
        carry = -carry;
        ASSERT(minute >= 0 && minute <= 59);
    } else {
        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 {
        m_minute = minute;
        m_hour = hour;
        return true;
    }
    if (!addDay(carry))
        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 UChar* src, unsigned length, unsigned start, unsigned& end)
{
    if (start >= 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, length, index, 2, hour) || hour < 0 || hour > 23)
        return false;
    index += 2;

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

    if (!toInt(src, length, 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 UChar* src, unsigned length, unsigned start, unsigned& end)
{
    ASSERT(src);
    unsigned index;
    if (!parseYear(src, length, start, index))
        return false;
    if (index >= length || src[index] != '-')
        return false;
    ++index;

    int month;
    if (!toInt(src, length, index, 2, month) || month < 1 || month > 12)
        return false;
    --month;
    // No support for months before Gregorian calendar.
    if (beforeGregorianStartDate(m_year, month, gregorianStartDay))
        return false;
    m_month = month;
    end = index + 2;
    m_type = Month;
    return true;
}

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

    int day;
    if (!toInt(src, length, index, 2, day) || day < 1 || day > maxDayOfMonth(m_year, m_month))
        return false;
    // No support for dates before Gregorian calendar.
    if (m_year == gregorianStartYear && m_month == gregorianStartMonth && day < gregorianStartDay)
        return false;
    m_monthDay = day;
    end = index + 2;
    m_type = Date;
    return true;
}

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

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

    int week;
    if (!toInt(src, length, index, 2, week) || week < 1 || week > maxWeekNumberInYear())
        return false;
    // No support for years older than or equals to Gregorian calendar start year.
    if (m_year <= gregorianStartYear)
        return false;
    m_week = week;
    end = index + 2;
    m_type = Week;
    return true;
}

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

    int minute;
    if (!toInt(src, length, 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 < length && src[index] == ':') {
        if (toInt(src, length, index + 1, 2, second) && second >= 0 && second <= 59) {
            index += 3;

            // Optional fractional second part.
            if (index < length && src[index] == '.') {
                unsigned digitsLength = countDigits(src, length, index + 1);
                if (digitsLength >  0) {
                    ++index;
                    bool ok;
                    if (digitsLength == 1) {
                        ok = toInt(src, length, index, 1, millisecond);
                        millisecond *= 100;
                    } else if (digitsLength == 2) {
                        ok = toInt(src, length, index, 2, millisecond);
                        millisecond *= 10;
                    } else // digitsLength >= 3
                        ok = toInt(src, length, index, 3, millisecond);
                    ASSERT(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 UChar* src, unsigned length, unsigned start, unsigned& end)
{
    ASSERT(src);
    unsigned index;
    if (!parseDate(src, length, start, index))
        return false;
    if (index >= length)
        return false;
    if (src[index] != 'T')
        return false;
    ++index;
    if (!parseTime(src, length, index, end))
        return false;
    m_type = DateTimeLocal;
    return true;
}

bool DateComponents::parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
{
    ASSERT(src);
    unsigned index;
    if (!parseDate(src, length, start, index))
        return false;
    if (index >= length)
        return false;
    if (src[index] != 'T')
        return false;
    ++index;
    if (!parseTime(src, length, index, index))
        return false;
    if (!parseTimeZone(src, length, index, end))
        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 (!isfinite(ms))
        return false;
    if (!setMillisecondsSinceEpochForDateInternal(round(ms)))
        return false;
    if (beforeGregorianStartDate(m_year, m_month, m_monthDay))
        return false;
    m_type = Date;
    return true;
}

bool DateComponents::setMillisecondsSinceEpochForDateTime(double ms)
{
    m_type = Invalid;
    if (!isfinite(ms))
        return false;
    ms = round(ms);
    setMillisecondsSinceMidnightInternal(positiveFmod(ms, msPerDay));
    if (!setMillisecondsSinceEpochForDateInternal(ms))
        return false;
    if (beforeGregorianStartDate(m_year, m_month, m_monthDay))
        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 (!isfinite(ms))
        return false;
    if (!setMillisecondsSinceEpochForDateInternal(round(ms)))
        return false;
    // Ignore m_monthDay updated by setMillisecondsSinceEpochForDateInternal().
    if (beforeGregorianStartDate(m_year, m_month, gregorianStartDay))
        return false;
    m_type = Month;
    return true;
}

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

bool DateComponents::setMonthsSinceEpoch(double months)
{
    if (!isfinite(months))
        return false;
    months = round(months);
    double doubleMonth = positiveFmod(months, 12);
    double doubleYear = 1970 + (months - doubleMonth) / 12;
    if (doubleYear < gregorianStartYear || numeric_limits<int>::max() < doubleYear)
        return false;
    int year = static_cast<int>(doubleYear);
    int month = static_cast<int>(doubleMonth);
    if (beforeGregorianStartDate(year, month, gregorianStartDay))
        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 (!isfinite(ms))
        return false;
    ms = round(ms);

    m_year = msToYear(ms);
    // We don't support gregorianStartYear. Week numbers are undefined in that year.
    if (m_year <= gregorianStartYear)
        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 <= gregorianStartYear)
            return false;
        m_week = maxWeekNumberInYear();
    } else {
        m_week = ((yearDay - offset) / 7) + 1;
        if (m_week > maxWeekNumberInYear()) {
            m_year++;
            m_week = 1;
        }
    }
    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
