/*
 * 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 "platform/wtf/ASCIICType.h"
#include "platform/wtf/DateMath.h"
#include "platform/wtf/MathExtras.h"
#include "platform/wtf/text/WTFString.h"

namespace blink {

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

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

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

static const int kDaysInMonth[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 kDaysInMonth[month];
  return IsLeapYear(year) ? 29 : 28;
}

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

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

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

int DateComponents::WeekDay() const {
  return DayOfWeek(year_, month_, month_day_);
}

int DateComponents::MaxWeekNumberInYear() const {
  int day = DayOfWeek(year_, 0, 1);  // January 1.
  return day == kThursday || (day == kWednesday && IsLeapYear(year_))
             ? kMaximumWeekNumber
             : kMaximumWeekNumber - 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 parse_start,
                  unsigned parse_length,
                  int& out) {
  if (parse_start + parse_length > src.length() || !parse_length)
    return false;
  int value = 0;
  unsigned current = parse_start;
  unsigned end = current + parse_length;

  // 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 digits_length = CountDigits(src, start);
  // Needs at least 4 digits according to the standard.
  if (digits_length < 4)
    return false;
  int year;
  if (!ToInt(src, start, digits_length, year))
    return false;
  if (year < MinimumYear() || year > MaximumYear())
    return false;
  year_ = year;
  end = start + digits_length;
  return true;
}

static bool WithinHTMLDateLimits(int year, int month) {
  if (year < DateComponents::MinimumYear())
    return false;
  if (year < DateComponents::MaximumYear())
    return true;
  return month <= kMaximumMonthInMaximumYear;
}

static bool WithinHTMLDateLimits(int year, int month, int month_day) {
  if (year < DateComponents::MinimumYear())
    return false;
  if (year < DateComponents::MaximumYear())
    return true;
  if (month < kMaximumMonthInMaximumYear)
    return true;
  return month_day <= kMaximumDayInMaximumMonth;
}

static bool WithinHTMLDateLimits(int year,
                                 int month,
                                 int month_day,
                                 int hour,
                                 int minute,
                                 int second,
                                 int millisecond) {
  if (year < DateComponents::MinimumYear())
    return false;
  if (year < DateComponents::MaximumYear())
    return true;
  if (month < kMaximumMonthInMaximumYear)
    return true;
  if (month_day < kMaximumDayInMaximumMonth)
    return true;
  if (month_day > kMaximumDayInMaximumMonth)
    return false;
  // (year, month, monthDay) =
  // (maximumYear, maximumMonthInMaximumYear, maximumDayInMaximumMonth)
  return !hour && !minute && !second && !millisecond;
}

bool DateComponents::AddDay(int day_diff) {
  DCHECK(month_day_);

  int day = month_day_ + day_diff;
  if (day > MaxDayOfMonth(year_, month_)) {
    day = month_day_;
    int year = year_;
    int month = month_;
    int max_day = MaxDayOfMonth(year, month);
    for (; day_diff > 0; --day_diff) {
      ++day;
      if (day > max_day) {
        day = 1;
        ++month;
        if (month >= 12) {  // month is 0-origin.
          month = 0;
          ++year;
        }
        max_day = MaxDayOfMonth(year, month);
      }
    }
    if (!WithinHTMLDateLimits(year, month, day))
      return false;
    year_ = year;
    month_ = month;
  } else if (day < 1) {
    int month = month_;
    int year = year_;
    day = month_day_;
    for (; day_diff < 0; ++day_diff) {
      --day;
      if (day < 1) {
        --month;
        if (month < 0) {
          month = 11;
          --year;
        }
        day = MaxDayOfMonth(year, month);
      }
    }
    if (!WithinHTMLDateLimits(year, month, day))
      return false;
    year_ = year;
    month_ = month;
  } else {
    if (!WithinHTMLDateLimits(year_, month_, day))
      return false;
  }
  month_day_ = 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.
  DCHECK(WithinHTMLDateLimits(year_, month_, month_day_));

  int carry;
  // minute can be negative or greater than 59.
  minute += minute_;
  if (minute > 59) {
    carry = minute / 60;
    minute = minute % 60;
  } else if (minute < 0) {
    carry = (59 - minute) / 60;
    minute += carry * 60;
    carry = -carry;
    DCHECK_GE(minute, 0);
    DCHECK_LE(minute, 59);
  } else {
    if (!WithinHTMLDateLimits(year_, month_, month_day_, hour_, minute, second_,
                              millisecond_))
      return false;
    minute_ = minute;
    return true;
  }

  int hour = hour_ + carry;
  if (hour > 23) {
    carry = hour / 24;
    hour = hour % 24;
  } else if (hour < 0) {
    carry = (23 - hour) / 24;
    hour += carry * 24;
    carry = -carry;
    DCHECK_GE(hour, 0);
    DCHECK_LE(hour, 23);
  } else {
    if (!WithinHTMLDateLimits(year_, month_, month_day_, hour, minute, second_,
                              millisecond_))
      return false;
    minute_ = minute;
    hour_ = hour;
    return true;
  }
  if (!AddDay(carry))
    return false;
  if (!WithinHTMLDateLimits(year_, month_, month_day_, hour, minute, second_,
                            millisecond_))
    return false;
  minute_ = minute;
  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(year_, month))
    return false;
  month_ = month;
  end = index + 2;
  type_ = kMonth;
  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(year_, month_))
    return false;
  if (!WithinHTMLDateLimits(year_, month_, day))
    return false;
  month_day_ = day;
  end = index + 2;
  type_ = kDate;
  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 < kMinimumWeekNumber ||
      week > MaxWeekNumberInYear())
    return false;
  if (year_ == MaximumYear() && week > kMaximumWeekInMaximumYear)
    return false;
  week_ = week;
  end = index + 2;
  type_ = kWeek;
  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 digits_length = CountDigits(src, index + 1);
        if (digits_length > 0) {
          ++index;
          bool ok;
          if (digits_length == 1) {
            ok = ToInt(src, index, 1, millisecond);
            millisecond *= 100;
          } else if (digits_length == 2) {
            ok = ToInt(src, index, 2, millisecond);
            millisecond *= 10;
          } else if (digits_length == 3) {
            ok = ToInt(src, index, 3, millisecond);
          } else {  // digitsLength >= 4
            return false;
          }
          DCHECK(ok);
          index += digits_length;
        }
      }
    }
  }
  hour_ = hour;
  minute_ = minute;
  second_ = second;
  millisecond_ = millisecond;
  end = index;
  type_ = kTime;
  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(year_, month_, month_day_, hour_, minute_, second_,
                            millisecond_))
    return false;
  type_ = kDateTimeLocal;
  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 ms_in_day) {
  DCHECK_GE(ms_in_day, 0);
  DCHECK_LT(ms_in_day, kMsPerDay);
  millisecond_ = static_cast<int>(fmod(ms_in_day, kMsPerSecond));
  double value = std::floor(ms_in_day / kMsPerSecond);
  second_ = static_cast<int>(fmod(value, kSecondsPerMinute));
  value = std::floor(value / kSecondsPerMinute);
  minute_ = static_cast<int>(fmod(value, kMinutesPerHour));
  hour_ = static_cast<int>(value / kMinutesPerHour);
}

bool DateComponents::SetMillisecondsSinceEpochForDateInternal(double ms) {
  year_ = MsToYear(ms);
  int year_day = DayInYear(ms, year_);
  month_ = MonthFromDayInYear(year_day, IsLeapYear(year_));
  month_day_ = DayInMonthFromDayInYear(year_day, IsLeapYear(year_));
  return true;
}

bool DateComponents::SetMillisecondsSinceEpochForDate(double ms) {
  type_ = kInvalid;
  if (!std::isfinite(ms))
    return false;
  if (!SetMillisecondsSinceEpochForDateInternal(round(ms)))
    return false;
  if (!WithinHTMLDateLimits(year_, month_, month_day_))
    return false;
  type_ = kDate;
  return true;
}

bool DateComponents::SetMillisecondsSinceEpochForDateTime(double ms) {
  type_ = kInvalid;
  if (!std::isfinite(ms))
    return false;
  ms = round(ms);
  SetMillisecondsSinceMidnightInternal(PositiveFmod(ms, kMsPerDay));
  if (!SetMillisecondsSinceEpochForDateInternal(ms))
    return false;
  if (!WithinHTMLDateLimits(year_, month_, month_day_, hour_, minute_, second_,
                            millisecond_))
    return false;
  type_ = kDateTime;
  return true;
}

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

bool DateComponents::SetMillisecondsSinceEpochForMonth(double ms) {
  type_ = kInvalid;
  if (!std::isfinite(ms))
    return false;
  if (!SetMillisecondsSinceEpochForDateInternal(round(ms)))
    return false;
  if (!WithinHTMLDateLimits(year_, month_))
    return false;
  type_ = kMonth;
  return true;
}

bool DateComponents::SetMillisecondsSinceMidnight(double ms) {
  type_ = kInvalid;
  if (!std::isfinite(ms))
    return false;
  SetMillisecondsSinceMidnightInternal(PositiveFmod(round(ms), kMsPerDay));
  type_ = kTime;
  return true;
}

bool DateComponents::SetMonthsSinceEpoch(double months) {
  if (!std::isfinite(months))
    return false;
  months = round(months);
  double double_month = PositiveFmod(months, 12);
  double double_year = 1970 + (months - double_month) / 12;
  if (double_year < MinimumYear() || MaximumYear() < double_year)
    return false;
  int year = static_cast<int>(double_year);
  int month = static_cast<int>(double_month);
  if (!WithinHTMLDateLimits(year, month))
    return false;
  year_ = year;
  month_ = month;
  type_ = kMonth;
  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 offset_to1st_week_start = 1 - DayOfWeek(year, 0, 1);
  if (offset_to1st_week_start <= -4)
    offset_to1st_week_start += 7;
  return offset_to1st_week_start;
}

bool DateComponents::SetMillisecondsSinceEpochForWeek(double ms) {
  type_ = kInvalid;
  if (!std::isfinite(ms))
    return false;
  ms = round(ms);

  year_ = MsToYear(ms);
  if (year_ < MinimumYear() || year_ > MaximumYear())
    return false;

  int year_day = DayInYear(ms, year_);
  int offset = OffsetTo1stWeekStart(year_);
  if (year_day < offset) {
    // The day belongs to the last week of the previous year.
    year_--;
    if (year_ <= MinimumYear())
      return false;
    week_ = MaxWeekNumberInYear();
  } else {
    week_ = ((year_day - offset) / 7) + 1;
    if (week_ > MaxWeekNumberInYear()) {
      year_++;
      week_ = 1;
    }
    if (year_ > MaximumYear() ||
        (year_ == MaximumYear() && week_ > kMaximumWeekInMaximumYear))
      return false;
  }
  type_ = kWeek;
  return true;
}

bool DateComponents::SetWeek(int year, int week_number) {
  type_ = kInvalid;
  if (year < MinimumYear() || year > MaximumYear())
    return false;
  year_ = year;
  if (week_number < 1 || week_number > MaxWeekNumberInYear())
    return false;
  week_ = week_number;
  type_ = kWeek;
  return true;
}

double DateComponents::MillisecondsSinceEpochForTime() const {
  DCHECK(type_ == kTime || type_ == kDateTime || type_ == kDateTimeLocal);
  return ((hour_ * kMinutesPerHour + minute_) * kSecondsPerMinute + second_) *
             kMsPerSecond +
         millisecond_;
}

double DateComponents::MillisecondsSinceEpoch() const {
  switch (type_) {
    case kDate:
      return DateToDaysFrom1970(year_, month_, month_day_) * kMsPerDay;
    case kDateTime:
    case kDateTimeLocal:
      return DateToDaysFrom1970(year_, month_, month_day_) * kMsPerDay +
             MillisecondsSinceEpochForTime();
    case kMonth:
      return DateToDaysFrom1970(year_, month_, 1) * kMsPerDay;
    case kTime:
      return MillisecondsSinceEpochForTime();
    case kWeek:
      return (DateToDaysFrom1970(year_, 0, 1) + OffsetTo1stWeekStart(year_) +
              (week_ - 1) * 7) *
             kMsPerDay;
    case kInvalid:
      break;
  }
  NOTREACHED();
  return InvalidMilliseconds();
}

double DateComponents::MonthsSinceEpoch() const {
  DCHECK_EQ(type_, kMonth);
  return (year_ - 1970) * 12 + month_;
}

String DateComponents::ToStringForTime(SecondFormat format) const {
  DCHECK(type_ == kDateTime || type_ == kDateTimeLocal || type_ == kTime);
  SecondFormat effective_format = format;
  if (millisecond_)
    effective_format = kMillisecond;
  else if (format == kNone && second_)
    effective_format = kSecond;

  switch (effective_format) {
    default:
      NOTREACHED();
      FALLTHROUGH;
    case kNone:
      return String::Format("%02d:%02d", hour_, minute_);
    case kSecond:
      return String::Format("%02d:%02d:%02d", hour_, minute_, second_);
    case kMillisecond:
      return String::Format("%02d:%02d:%02d.%03d", hour_, minute_, second_,
                            millisecond_);
  }
}

String DateComponents::ToString(SecondFormat format) const {
  switch (type_) {
    case kDate:
      return String::Format("%04d-%02d-%02d", year_, month_ + 1, month_day_);
    case kDateTime:
      return String::Format("%04d-%02d-%02dT", year_, month_ + 1, month_day_) +
             ToStringForTime(format) + String("Z");
    case kDateTimeLocal:
      return String::Format("%04d-%02d-%02dT", year_, month_ + 1, month_day_) +
             ToStringForTime(format);
    case kMonth:
      return String::Format("%04d-%02d", year_, month_ + 1);
    case kTime:
      return ToStringForTime(format);
    case kWeek:
      return String::Format("%04d-W%02d", year_, week_);
    case kInvalid:
      break;
  }
  NOTREACHED();
  return String("(Invalid DateComponents)");
}

}  // namespace blink
