// Copyright (c) 2012, 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.

part of intl;

/// A class for holding onto the data for a date so that it can be built
/// up incrementally.
class _DateBuilder {
  // Default the date values to the EPOCH so that there's a valid date
  // in case the format doesn't set them.
  int year = 1970,
      month = 1,
      day = 1,
      hour = 0,
      minute = 0,
      second = 0,
      fractionalSecond = 0;
  bool pm = false;
  bool utc = false;

  // Functions that exist just to be closurized so we can pass them to a general
  // method.
  void setYear(x) {
    year = x;
  }

  void setMonth(x) {
    month = x;
  }

  void setDay(x) {
    day = x;
  }

  void setHour(x) {
    hour = x;
  }

  void setMinute(x) {
    minute = x;
  }

  void setSecond(x) {
    second = x;
  }

  void setFractionalSecond(x) {
    fractionalSecond = x;
  }

  get hour24 => pm ? hour + 12 : hour;

  /// Verify that we correspond to a valid date. This will reject out of
  /// range values, even if the DateTime constructor would accept them. An
  /// invalid message will result in throwing a [FormatException].
  verify(String s) {
    _verify(month, 1, 12, "month", s);
    _verify(hour24, 0, 23, "hour", s);
    _verify(minute, 0, 59, "minute", s);
    _verify(second, 0, 59, "second", s);
    _verify(fractionalSecond, 0, 999, "fractional second", s);
    // Verifying the day is tricky, because it depends on the month. Create
    // our resulting date and then verify that our values agree with it
    // as an additional verification. And since we're doing that, also
    // check the year, which we otherwise can't verify, and the hours,
    // which will catch cases like "14:00:00 PM".
    var date = asDate();
    _verify(hour24, date.hour, date.hour, "hour", s, date);
    _verify(day, date.day, date.day, "day", s, date);
    _verify(year, date.year, date.year, "year", s, date);
  }

  _verify(int value, int min, int max, String desc, String originalInput,
      [DateTime parsed]) {
    if (value < min || value > max) {
      var parsedDescription = parsed == null ? "" : " Date parsed as $parsed.";
      throw new FormatException(
          "Error parsing $originalInput, invalid $desc value: $value."
          " Expected value between $min and $max.$parsedDescription");
    }
  }

  /// Return a date built using our values. If no date portion is set,
  /// use the "Epoch" of January 1, 1970.
  DateTime asDate({int retries: 10}) {
    // TODO(alanknight): Validate the date, especially for things which
    // can crash the VM, e.g. large month values.
    var result;
    if (utc) {
      result = new DateTime.utc(
          year, month, day, hour24, minute, second, fractionalSecond);
    } else {
      result = new DateTime(
          year, month, day, hour24, minute, second, fractionalSecond);
      // TODO(alanknight): Issue 15560 means non-UTC dates occasionally come out
      // in UTC, or, alternatively, are constructed as if in UTC and then have
      // the offset subtracted. If that happens, retry, several times if
      // necessary.
      if (retries > 0 && (result.hour != hour24 || result.day != day)) {
        result = asDate(retries: retries - 1);
      }
    }
    return result;
  }
}

/// A simple and not particularly general stream class to make parsing
/// dates from strings simpler. It is general enough to operate on either
/// lists or strings.
// TODO(alanknight): With the improvements to the collection libraries
// since this was written we might be able to get rid of it entirely
// in favor of e.g. aString.split('') giving us an iterable of one-character
// strings, or else make the implementation trivial. And consider renaming,
// as _Stream is now just confusing with the system Streams.
class _Stream {
  var contents;
  int index = 0;

  _Stream(this.contents);

  bool atEnd() => index >= contents.length;

  next() => contents[index++];

  /// Return the next [howMany] items, or as many as there are remaining.
  /// Advance the stream by that many positions.
  read([int howMany = 1]) {
    var result = peek(howMany);
    index += howMany;
    return result;
  }

  /// Does the input start with the given string, if we start from the
  /// current position.
  bool startsWith(String pattern) {
    if (contents is String) return contents.startsWith(pattern, index);
    return pattern == peek(pattern.length);
  }

  /// Return the next [howMany] items, or as many as there are remaining.
  /// Does not modify the stream position.
  peek([int howMany = 1]) {
    var result;
    if (contents is String) {
      String stringContents = contents;
      result = stringContents.substring(
          index, min(index + howMany, stringContents.length));
    } else {
      // Assume List
      result = contents.sublist(index, index + howMany);
    }
    return result;
  }

  /// Return the remaining contents of the stream
  rest() => peek(contents.length - index);

  /// Find the index of the first element for which [f] returns true.
  /// Advances the stream to that position.
  int findIndex(Function f) {
    while (!atEnd()) {
      if (f(next())) return index - 1;
    }
    return null;
  }

  /// Find the indexes of all the elements for which [f] returns true.
  /// Leaves the stream positioned at the end.
  List findIndexes(Function f) {
    var results = [];
    while (!atEnd()) {
      if (f(next())) results.add(index - 1);
    }
    return results;
  }

  /// Assuming that the contents are characters, read as many digits as we
  /// can see and then return the corresponding integer, advancing the receiver.
  ///
  /// For non-ascii digits, the optional arguments are a regular expression
  /// [digitMatcher] to find the next integer, and the codeUnit of the local
  /// zero [zeroDigit].
  int nextInteger({RegExp digitMatcher, int zeroDigit}) {
    var string =
        (digitMatcher ?? DateFormat._asciiDigitMatcher).stringMatch(rest());
    if (string == null || string.isEmpty) return null;
    read(string.length);
    if (zeroDigit != null && zeroDigit != DateFormat._asciiZeroCodeUnit) {
      // Trying to optimize this, as it might get called a lot.
      var oldDigits = string.codeUnits;
      var newDigits = new List<int>(string.length);
      for (var i = 0; i < string.length; i++) {
        newDigits[i] = oldDigits[i] - zeroDigit + DateFormat._asciiZeroCodeUnit;
      }
      string = new String.fromCharCodes(newDigits);
    }
    return int.parse(string);
  }
}
