// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/date.h"

#include "src/conversions.h"
#include "src/objects-inl.h"
#include "src/objects.h"

#ifdef V8_INTL_SUPPORT
#include "src/intl.h"
#endif

namespace v8 {
namespace internal {


static const int kDaysIn4Years = 4 * 365 + 1;
static const int kDaysIn100Years = 25 * kDaysIn4Years - 1;
static const int kDaysIn400Years = 4 * kDaysIn100Years + 1;
static const int kDays1970to2000 = 30 * 365 + 7;
static const int kDaysOffset = 1000 * kDaysIn400Years + 5 * kDaysIn400Years -
                               kDays1970to2000;
static const int kYearsOffset = 400000;
static const char kDaysInMonths[] =
    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

DateCache::DateCache()
    : stamp_(0),
      tz_cache_(
#ifdef V8_INTL_SUPPORT
          FLAG_icu_timezone_data ? new ICUTimezoneCache()
                                 : base::OS::CreateTimezoneCache()
#else
          base::OS::CreateTimezoneCache()
#endif
              ) {
  ResetDateCache();
}

void DateCache::ResetDateCache() {
  static const int kMaxStamp = Smi::kMaxValue;
  if (stamp_->value() >= kMaxStamp) {
    stamp_ = Smi::kZero;
  } else {
    stamp_ = Smi::FromInt(stamp_->value() + 1);
  }
  DCHECK(stamp_ != Smi::FromInt(kInvalidStamp));
  for (int i = 0; i < kDSTSize; ++i) {
    ClearSegment(&dst_[i]);
  }
  dst_usage_counter_ = 0;
  before_ = &dst_[0];
  after_ = &dst_[1];
  ymd_valid_ = false;
#ifdef V8_INTL_SUPPORT
  if (!FLAG_icu_timezone_data) {
#endif
    local_offset_ms_ = kInvalidLocalOffsetInMs;
#ifdef V8_INTL_SUPPORT
  }
#endif
  tz_cache_->Clear();
  tz_name_ = nullptr;
  dst_tz_name_ = nullptr;
}

// ECMA 262 - ES#sec-timeclip TimeClip (time)
double DateCache::TimeClip(double time) {
  if (-kMaxTimeInMs <= time && time <= kMaxTimeInMs) {
    return DoubleToInteger(time) + 0.0;
  }
  return std::numeric_limits<double>::quiet_NaN();
}

void DateCache::ClearSegment(DST* segment) {
  segment->start_sec = kMaxEpochTimeInSec;
  segment->end_sec = -kMaxEpochTimeInSec;
  segment->offset_ms = 0;
  segment->last_used = 0;
}


void DateCache::YearMonthDayFromDays(
    int days, int* year, int* month, int* day) {
  if (ymd_valid_) {
    // Check conservatively if the given 'days' has
    // the same year and month as the cached 'days'.
    int new_day = ymd_day_ + (days - ymd_days_);
    if (new_day >= 1 && new_day <= 28) {
      ymd_day_ = new_day;
      ymd_days_ = days;
      *year = ymd_year_;
      *month = ymd_month_;
      *day = new_day;
      return;
    }
  }
  int save_days = days;

  days += kDaysOffset;
  *year = 400 * (days / kDaysIn400Years) - kYearsOffset;
  days %= kDaysIn400Years;

  DCHECK_EQ(save_days, DaysFromYearMonth(*year, 0) + days);

  days--;
  int yd1 = days / kDaysIn100Years;
  days %= kDaysIn100Years;
  *year += 100 * yd1;

  days++;
  int yd2 = days / kDaysIn4Years;
  days %= kDaysIn4Years;
  *year += 4 * yd2;

  days--;
  int yd3 = days / 365;
  days %= 365;
  *year += yd3;


  bool is_leap = (!yd1 || yd2) && !yd3;

  DCHECK_GE(days, -1);
  DCHECK(is_leap || (days >= 0));
  DCHECK((days < 365) || (is_leap && (days < 366)));
  DCHECK(is_leap == ((*year % 4 == 0) && (*year % 100 || (*year % 400 == 0))));
  DCHECK(is_leap || ((DaysFromYearMonth(*year, 0) + days) == save_days));
  DCHECK(!is_leap || ((DaysFromYearMonth(*year, 0) + days + 1) == save_days));

  days += is_leap;

  // Check if the date is after February.
  if (days >= 31 + 28 + BoolToInt(is_leap)) {
    days -= 31 + 28 + BoolToInt(is_leap);
    // Find the date starting from March.
    for (int i = 2; i < 12; i++) {
      if (days < kDaysInMonths[i]) {
        *month = i;
        *day = days + 1;
        break;
      }
      days -= kDaysInMonths[i];
    }
  } else {
    // Check January and February.
    if (days < 31) {
      *month = 0;
      *day = days + 1;
    } else {
      *month = 1;
      *day = days - 31 + 1;
    }
  }
  DCHECK(DaysFromYearMonth(*year, *month) + *day - 1 == save_days);
  ymd_valid_ = true;
  ymd_year_ = *year;
  ymd_month_ = *month;
  ymd_day_ = *day;
  ymd_days_ = save_days;
}


int DateCache::DaysFromYearMonth(int year, int month) {
  static const int day_from_month[] = {0, 31, 59, 90, 120, 151,
                                       181, 212, 243, 273, 304, 334};
  static const int day_from_month_leap[] = {0, 31, 60, 91, 121, 152,
                                            182, 213, 244, 274, 305, 335};

  year += month / 12;
  month %= 12;
  if (month < 0) {
    year--;
    month += 12;
  }

  DCHECK_GE(month, 0);
  DCHECK_LT(month, 12);

  // year_delta is an arbitrary number such that:
  // a) year_delta = -1 (mod 400)
  // b) year + year_delta > 0 for years in the range defined by
  //    ECMA 262 - 15.9.1.1, i.e. upto 100,000,000 days on either side of
  //    Jan 1 1970. This is required so that we don't run into integer
  //    division of negative numbers.
  // c) there shouldn't be an overflow for 32-bit integers in the following
  //    operations.
  static const int year_delta = 399999;
  static const int base_day = 365 * (1970 + year_delta) +
                              (1970 + year_delta) / 4 -
                              (1970 + year_delta) / 100 +
                              (1970 + year_delta) / 400;

  int year1 = year + year_delta;
  int day_from_year = 365 * year1 +
                      year1 / 4 -
                      year1 / 100 +
                      year1 / 400 -
                      base_day;

  if ((year % 4 != 0) || (year % 100 == 0 && year % 400 != 0)) {
    return day_from_year + day_from_month[month];
  }
  return day_from_year + day_from_month_leap[month];
}


void DateCache::BreakDownTime(int64_t time_ms, int* year, int* month, int* day,
                              int* weekday, int* hour, int* min, int* sec,
                              int* ms) {
  int const days = DaysFromTime(time_ms);
  int const time_in_day_ms = TimeInDay(time_ms, days);
  YearMonthDayFromDays(days, year, month, day);
  *weekday = Weekday(days);
  *hour = time_in_day_ms / (60 * 60 * 1000);
  *min = (time_in_day_ms / (60 * 1000)) % 60;
  *sec = (time_in_day_ms / 1000) % 60;
  *ms = time_in_day_ms % 1000;
}

// Implements LocalTimeZonedjustment(t, isUTC)
// ECMA 262 - ES#sec-local-time-zone-adjustment
int DateCache::GetLocalOffsetFromOS(int64_t time_ms, bool is_utc) {
  double offset;
#ifdef V8_INTL_SUPPORT
  if (FLAG_icu_timezone_data) {
    offset = tz_cache_->LocalTimeOffset(static_cast<double>(time_ms), is_utc);
  } else {
#endif
    // When ICU timezone data is not used, we need to compute the timezone
    // offset for a given local time.
    //
    // The following shows that using DST for (t - LocalTZA - hour) produces
    // correct conversion where LocalTZA is the timezone offset in winter (no
    // DST) and the timezone offset is assumed to have no historical change.
    // Note that it does not work for the past and the future if LocalTZA (no
    // DST) is different from the current LocalTZA (no DST). For instance,
    // this will break for Europe/Moscow in 2012 ~ 2013 because LocalTZA was
    // 4h instead of the current 3h (as of 2018).
    //
    // Consider transition to DST at local time L1.
    // Let L0 = L1 - hour, L2 = L1 + hour,
    //     U1 = UTC time that corresponds to L1,
    //     U0 = U1 - hour.
    // Transitioning to DST moves local clock one hour forward L1 => L2, so
    // U0 = UTC time that corresponds to L0 = L0 - LocalTZA,
    // U1 = UTC time that corresponds to L1 = L1 - LocalTZA,
    // U1 = UTC time that corresponds to L2 = L2 - LocalTZA - hour.
    // Note that DST(U0 - hour) = 0, DST(U0) = 0, DST(U1) = 1.
    // U0 = L0 - LocalTZA - DST(L0 - LocalTZA - hour),
    // U1 = L1 - LocalTZA - DST(L1 - LocalTZA - hour),
    // U1 = L2 - LocalTZA - DST(L2 - LocalTZA - hour).
    //
    // Consider transition from DST at local time L1.
    // Let L0 = L1 - hour,
    //     U1 = UTC time that corresponds to L1,
    //     U0 = U1 - hour, U2 = U1 + hour.
    // Transitioning from DST moves local clock one hour back L1 => L0, so
    // U0 = UTC time that corresponds to L0 (before transition)
    //    = L0 - LocalTZA - hour.
    // U1 = UTC time that corresponds to L0 (after transition)
    //    = L0 - LocalTZA = L1 - LocalTZA - hour
    // U2 = UTC time that corresponds to L1 = L1 - LocalTZA.
    // Note that DST(U0) = 1, DST(U1) = 0, DST(U2) = 0.
    // U0 = L0 - LocalTZA - DST(L0 - LocalTZA - hour) = L0 - LocalTZA - DST(U0).
    // U2 = L1 - LocalTZA - DST(L1 - LocalTZA - hour) = L1 - LocalTZA - DST(U1).
    // It is impossible to get U1 from local time.
    if (local_offset_ms_ == kInvalidLocalOffsetInMs) {
      // This gets the constant LocalTZA (arguments are ignored).
      local_offset_ms_ =
          tz_cache_->LocalTimeOffset(static_cast<double>(time_ms), is_utc);
    }
    offset = local_offset_ms_;
    if (!is_utc) {
      const int kMsPerHour = 3600 * 1000;
      time_ms -= (offset + kMsPerHour);
    }
    offset += DaylightSavingsOffsetInMs(time_ms);
#ifdef V8_INTL_SUPPORT
  }
#endif
  DCHECK_LT(offset, kInvalidLocalOffsetInMs);
  return static_cast<int>(offset);
}

void DateCache::ExtendTheAfterSegment(int time_sec, int offset_ms) {
  if (after_->offset_ms == offset_ms &&
      after_->start_sec <= time_sec + kDefaultDSTDeltaInSec &&
      time_sec <= after_->end_sec) {
    // Extend the after_ segment.
    after_->start_sec = time_sec;
  } else {
    // The after_ segment is either invalid or starts too late.
    if (after_->start_sec <= after_->end_sec) {
      // If the after_ segment is valid, replace it with a new segment.
      after_ = LeastRecentlyUsedDST(before_);
    }
    after_->start_sec = time_sec;
    after_->end_sec = time_sec;
    after_->offset_ms = offset_ms;
    after_->last_used = ++dst_usage_counter_;
  }
}


int DateCache::DaylightSavingsOffsetInMs(int64_t time_ms) {
  int time_sec = (time_ms >= 0 && time_ms <= kMaxEpochTimeInMs)
      ? static_cast<int>(time_ms / 1000)
      : static_cast<int>(EquivalentTime(time_ms) / 1000);

  // Invalidate cache if the usage counter is close to overflow.
  // Note that dst_usage_counter is incremented less than ten times
  // in this function.
  if (dst_usage_counter_ >= kMaxInt - 10) {
    dst_usage_counter_ = 0;
    for (int i = 0; i < kDSTSize; ++i) {
      ClearSegment(&dst_[i]);
    }
  }

  // Optimistic fast check.
  if (before_->start_sec <= time_sec &&
      time_sec <= before_->end_sec) {
    // Cache hit.
    before_->last_used = ++dst_usage_counter_;
    return before_->offset_ms;
  }

  ProbeDST(time_sec);

  DCHECK(InvalidSegment(before_) || before_->start_sec <= time_sec);
  DCHECK(InvalidSegment(after_) || time_sec < after_->start_sec);

  if (InvalidSegment(before_)) {
    // Cache miss.
    before_->start_sec = time_sec;
    before_->end_sec = time_sec;
    before_->offset_ms = GetDaylightSavingsOffsetFromOS(time_sec);
    before_->last_used = ++dst_usage_counter_;
    return before_->offset_ms;
  }

  if (time_sec <= before_->end_sec) {
    // Cache hit.
    before_->last_used = ++dst_usage_counter_;
    return before_->offset_ms;
  }

  if (time_sec > before_->end_sec + kDefaultDSTDeltaInSec) {
    // If the before_ segment ends too early, then just
    // query for the offset of the time_sec
    int offset_ms = GetDaylightSavingsOffsetFromOS(time_sec);
    ExtendTheAfterSegment(time_sec, offset_ms);
    // This swap helps the optimistic fast check in subsequent invocations.
    DST* temp = before_;
    before_ = after_;
    after_ = temp;
    return offset_ms;
  }

  // Now the time_sec is between
  // before_->end_sec and before_->end_sec + default DST delta.
  // Update the usage counter of before_ since it is going to be used.
  before_->last_used = ++dst_usage_counter_;

  // Check if after_ segment is invalid or starts too late.
  // Note that start_sec of invalid segments is kMaxEpochTimeInSec.
  if (before_->end_sec + kDefaultDSTDeltaInSec <= after_->start_sec) {
    int new_after_start_sec = before_->end_sec + kDefaultDSTDeltaInSec;
    int new_offset_ms = GetDaylightSavingsOffsetFromOS(new_after_start_sec);
    ExtendTheAfterSegment(new_after_start_sec, new_offset_ms);
  } else {
    DCHECK(!InvalidSegment(after_));
    // Update the usage counter of after_ since it is going to be used.
    after_->last_used = ++dst_usage_counter_;
  }

  // Now the time_sec is between before_->end_sec and after_->start_sec.
  // Only one daylight savings offset change can occur in this interval.

  if (before_->offset_ms == after_->offset_ms) {
    // Merge two segments if they have the same offset.
    before_->end_sec = after_->end_sec;
    ClearSegment(after_);
    return before_->offset_ms;
  }

  // Binary search for daylight savings offset change point,
  // but give up if we don't find it in five iterations.
  for (int i = 4; i >= 0; --i) {
    int delta = after_->start_sec - before_->end_sec;
    int middle_sec = (i == 0) ? time_sec : before_->end_sec + delta / 2;
    int offset_ms = GetDaylightSavingsOffsetFromOS(middle_sec);
    if (before_->offset_ms == offset_ms) {
      before_->end_sec = middle_sec;
      if (time_sec <= before_->end_sec) {
        return offset_ms;
      }
    } else {
      DCHECK(after_->offset_ms == offset_ms);
      after_->start_sec = middle_sec;
      if (time_sec >= after_->start_sec) {
        // This swap helps the optimistic fast check in subsequent invocations.
        DST* temp = before_;
        before_ = after_;
        after_ = temp;
        return offset_ms;
      }
    }
  }
  return 0;
}


void DateCache::ProbeDST(int time_sec) {
  DST* before = nullptr;
  DST* after = nullptr;
  DCHECK(before_ != after_);

  for (int i = 0; i < kDSTSize; ++i) {
    if (dst_[i].start_sec <= time_sec) {
      if (before == nullptr || before->start_sec < dst_[i].start_sec) {
        before = &dst_[i];
      }
    } else if (time_sec < dst_[i].end_sec) {
      if (after == nullptr || after->end_sec > dst_[i].end_sec) {
        after = &dst_[i];
      }
    }
  }

  // If before or after segments were not found,
  // then set them to any invalid segment.
  if (before == nullptr) {
    before = InvalidSegment(before_) ? before_ : LeastRecentlyUsedDST(after);
  }
  if (after == nullptr) {
    after = InvalidSegment(after_) && before != after_
            ? after_ : LeastRecentlyUsedDST(before);
  }

  DCHECK_NOT_NULL(before);
  DCHECK_NOT_NULL(after);
  DCHECK(before != after);
  DCHECK(InvalidSegment(before) || before->start_sec <= time_sec);
  DCHECK(InvalidSegment(after) || time_sec < after->start_sec);
  DCHECK(InvalidSegment(before) || InvalidSegment(after) ||
         before->end_sec < after->start_sec);

  before_ = before;
  after_ = after;
}


DateCache::DST* DateCache::LeastRecentlyUsedDST(DST* skip) {
  DST* result = nullptr;
  for (int i = 0; i < kDSTSize; ++i) {
    if (&dst_[i] == skip) continue;
    if (result == nullptr || result->last_used > dst_[i].last_used) {
      result = &dst_[i];
    }
  }
  ClearSegment(result);
  return result;
}

}  // namespace internal
}  // namespace v8
