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

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

namespace blink {

// 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};

// '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::weekDay() const {
  return dayOfWeek(m_year, m_month, m_monthDay);
}

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)
    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;
}

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 = std::floor(msInDay / msPerSecond);
  m_second = static_cast<int>(fmod(value, secondsPerMinute));
  value = std::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;
}

bool DateComponents::setWeek(int year, int weekNumber) {
  m_type = Invalid;
  if (year < minimumYear() || year > maximumYear())
    return false;
  m_year = year;
  if (weekNumber < 1 || weekNumber > maxWeekNumberInYear())
    return false;
  m_week = weekNumber;
  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 blink
