/*
 * 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 "third_party/blink/renderer/platform/date_components.h"

#include <limits.h>
#include "third_party/blink/renderer/platform/wtf/ascii_ctype.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.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
