// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// @dart = 2.9

part of utilslib;

/**
 * General purpose date/time utilities.
 */
class DateUtils {
  // TODO(jmesserly): localized strings
  static const WEEKDAYS = const [
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday',
    'Sunday'
  ];

  static const YESTERDAY = 'Yesterday';

  static const MS_IN_WEEK = DateTime.daysPerWeek * Duration.millisecondsPerDay;

  // TODO(jmesserly): workaround for missing DateTime.fromDate in Dartium
  // Remove this once that is implemented. See b/5055106
  // Parse a string like: "Mon, 27 Jun 2011 15:22:00 -0700"
  static DateTime fromString(String text) {
    final parts = text.split(' ');
    if (parts.length == 1) {
      return _parseIsoDate(text);
    }

    if (parts.length != 6) {
      throw 'bad date format, expected 6 parts: $text';
    }

    // skip parts[0], the weekday

    int day = int.parse(parts[1]);

    final months = const [
      'Jan',
      'Feb',
      'Mar',
      'Apr',
      'May',
      'Jun',
      'Jul',
      'Aug',
      'Sep',
      'Oct',
      'Nov',
      'Dec'
    ];
    int month = months.indexOf(parts[2], 0) + 1;
    if (month < 0) {
      throw 'bad month, expected 3 letter month code, got: ${parts[2]}';
    }

    int year = int.parse(parts[3]);

    final timeParts = parts[4].split(':');
    if (timeParts.length != 3) {
      throw 'bad time format, expected 3 parts: ${parts[4]}';
    }

    int hours = int.parse(timeParts[0]);
    int minutes = int.parse(timeParts[1]);
    int seconds = int.parse(timeParts[2]);

    // TODO(jmesserly): TimeZone is not implemented in Dartium. This ugly
    // hack applies the timezone from the string to the final time
    int zoneOffset = int.parse(parts[5]) ~/ 100;

    // Pretend it's a UTC time
    DateTime result =
        new DateTime.utc(year, month, day, hours, minutes, seconds, 0);
    // Shift it to the proper zone, but it's still a UTC time
    result = result.subtract(new Duration(hours: zoneOffset));
    // Then render it as a local time
    return result.toLocal();
  }

  /** Parse a string like: 2011-07-19T22:03:04.000Z */
  // TODO(jmesserly): workaround for DateTime.fromDate, which has issues:
  //   * on Dart VM it doesn't handle all of ISO 8601. See b/5055106.
  //   * on DartC it doesn't work on Safari. See b/5062557.
  // Remove this once that function is fully implemented
  static DateTime _parseIsoDate(String text) {
    void ensure(bool value) {
      if (!value) {
        throw 'bad date format, expected YYYY-MM-DDTHH:MM:SS.mmmZ: $text';
      }
    }

    bool isUtc = text.endsWith('Z');
    if (isUtc) {
      text = text.substring(0, text.length - 1);
    }

    final parts = text.split('T');
    ensure(parts.length == 2);

    final date = parts[0].split('-');
    ensure(date.length == 3);

    final time = parts[1].split(':');
    ensure(time.length == 3);

    final seconds = time[2].split('.');
    ensure(seconds.length >= 1 && seconds.length <= 2);
    int milliseconds = 0;
    if (seconds.length == 2) {
      milliseconds = int.parse(seconds[1]);
    }

    return new DateTime(
        int.parse(date[0]),
        int.parse(date[1]),
        int.parse(date[2]),
        int.parse(time[0]),
        int.parse(time[1]),
        int.parse(seconds[0]),
        milliseconds);
  }

  /**
   * A date/time formatter that takes into account the current date/time:
   *  - if it's from today, just show the time
   *  - if it's from yesterday, just show 'Yesterday'
   *  - if it's from the same week, just show the weekday
   *  - otherwise, show just the date
   */
  static String toRecentTimeString(DateTime then) {
    bool datesAreEqual(DateTime d1, DateTime d2) {
      return (d1.year == d2.year) &&
          (d1.month == d2.month) &&
          (d1.day == d2.day);
    }

    final now = new DateTime.now();
    if (datesAreEqual(then, now)) {
      return toHourMinutesString(new Duration(
          days: 0,
          hours: then.hour,
          minutes: then.minute,
          seconds: then.second,
          milliseconds: then.millisecond));
    }

    final today = new DateTime(now.year, now.month, now.day, 0, 0, 0, 0);
    Duration delta = today.difference(then);
    if (delta.inMilliseconds < Duration.millisecondsPerDay) {
      return YESTERDAY;
    } else if (delta.inMilliseconds < MS_IN_WEEK) {
      return WEEKDAYS[getWeekday(then)];
    } else {
      // TODO(jmesserly): locale specific date format
      String twoDigits(int n) {
        if (n >= 10) return "${n}";
        return "0${n}";
      }

      String twoDigitMonth = twoDigits(then.month);
      String twoDigitDay = twoDigits(then.day);
      return "${then.year}-${twoDigitMonth}-${twoDigitDay}";
    }
  }

  // TODO(jmesserly): this is a workaround for unimplemented DateTime.weekday
  // Code inspired by v8/src/date.js
  static int getWeekday(DateTime dateTime) {
    final unixTimeStart = new DateTime(1970, 1, 1, 0, 0, 0, 0);
    int msSince1970 = dateTime.difference(unixTimeStart).inMilliseconds;
    int daysSince1970 = msSince1970 ~/ Duration.millisecondsPerDay;
    // 1970-1-1 was Thursday
    return ((daysSince1970 + DateTime.thursday) % DateTime.daysPerWeek);
  }

  /** Formats a time in H:MM A format */
  // TODO(jmesserly): should get 12 vs 24 hour clock setting from the locale
  static String toHourMinutesString(Duration duration) {
    assert(duration.inDays == 0);
    int hours = duration.inHours;
    String a;
    if (hours >= 12) {
      a = 'pm';
      if (hours != 12) {
        hours -= 12;
      }
    } else {
      a = 'am';
      if (hours == 0) {
        hours += 12;
      }
    }
    String twoDigits(int n) {
      if (n >= 10) return "${n}";
      return "0${n}";
    }

    String mm =
        twoDigits(duration.inMinutes.remainder(Duration.minutesPerHour));
    return "${hours}:${mm} ${a}";
  }
}
