// 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 dart._interceptors;

/**
 * The interceptor class for [String]. The compiler recognizes this
 * class as an interceptor, and changes references to [:this:] to
 * actually use the receiver of the method, which is generated as an extra
 * argument added to each member.
 */
@JsPeerInterface(name: 'String')
class JSString extends Interceptor implements String, JSIndexable<String> {
  const JSString();

  @notNull
  int codeUnitAt(@nullCheck int index) {
    // Suppress 2nd null check on index and null check on length
    // (JS String.length cannot be null).
    final len = this.length;
    if (index < 0 || index >= len) {
      throw new RangeError.index(index, this, 'index', null, len);
    }
    return JS('int', r'#.charCodeAt(#)', this, index);
  }

  @notNull
  Iterable<Match> allMatches(@nullCheck String string,
      [@nullCheck int start = 0]) {
    final len = string.length;
    if (0 > start || start > len) {
      throw new RangeError.range(start, 0, len);
    }
    return allMatchesInStringUnchecked(this, string, start);
  }

  Match matchAsPrefix(@nullCheck String string, [@nullCheck int start = 0]) {
    int stringLength = JS('!', '#.length', string);
    if (start < 0 || start > stringLength) {
      throw new RangeError.range(start, 0, stringLength);
    }
    int thisLength = JS('!', '#.length', this);
    if (start + thisLength > stringLength) return null;
    for (int i = 0; i < thisLength; i++) {
      if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) {
        return null;
      }
    }
    return new StringMatch(start, string, this);
  }

  @notNull
  String operator +(@nullCheck String other) {
    return JS('String', r'# + #', this, other);
  }

  @notNull
  bool endsWith(@nullCheck String other) {
    var otherLength = other.length;
    var thisLength = this.length;
    if (otherLength > thisLength) return false;
    return other == substring(thisLength - otherLength);
  }

  @notNull
  String replaceAll(Pattern from, @nullCheck String to) {
    return stringReplaceAllUnchecked(this, from, to);
  }

  @notNull
  String replaceAllMapped(Pattern from, String convert(Match match)) {
    return this.splitMapJoin(from, onMatch: convert);
  }

  @notNull
  String splitMapJoin(Pattern from,
      {String onMatch(Match match), String onNonMatch(String nonMatch)}) {
    return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch);
  }

  @notNull
  String replaceFirst(Pattern from, @nullCheck String to,
      [@nullCheck int startIndex = 0]) {
    RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
    return stringReplaceFirstUnchecked(this, from, to, startIndex);
  }

  @notNull
  String replaceFirstMapped(
      Pattern from, @nullCheck String replace(Match match),
      [@nullCheck int startIndex = 0]) {
    RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
    return stringReplaceFirstMappedUnchecked(this, from, replace, startIndex);
  }

  @notNull
  List<String> split(@nullCheck Pattern pattern) {
    if (pattern is String) {
      return new JSArray.of(JS('', r'#.split(#)', this, pattern));
    } else if (pattern is JSSyntaxRegExp && regExpCaptureCount(pattern) == 0) {
      var re = regExpGetNative(pattern);
      return new JSArray.of(JS('', r'#.split(#)', this, re));
    } else {
      return _defaultSplit(pattern);
    }
  }

  @notNull
  String replaceRange(
      @nullCheck int start, int end, @nullCheck String replacement) {
    end = RangeError.checkValidRange(start, end, this.length);
    return stringReplaceRangeUnchecked(this, start, end, replacement);
  }

  @notNull
  List<String> _defaultSplit(Pattern pattern) {
    List<String> result = <String>[];
    // End of most recent match. That is, start of next part to add to result.
    int start = 0;
    // Length of most recent match.
    // Set >0, so no match on the empty string causes the result to be [""].
    int length = 1;
    for (var match in pattern.allMatches(this)) {
      @notNull
      int matchStart = match.start;
      @notNull
      int matchEnd = match.end;
      length = matchEnd - matchStart;
      if (length == 0 && start == matchStart) {
        // An empty match right after another match is ignored.
        // This includes an empty match at the start of the string.
        continue;
      }
      int end = matchStart;
      result.add(this.substring(start, end));
      start = matchEnd;
    }
    if (start < this.length || length > 0) {
      // An empty match at the end of the string does not cause a "" at the end.
      // A non-empty match ending at the end of the string does add a "".
      result.add(this.substring(start));
    }
    return result;
  }

  @notNull
  bool startsWith(Pattern pattern, [@nullCheck int index = 0]) {
    // Suppress null check on length and all but the first
    // reference to index.
    int length = JS('int', '#.length', this);
    if (index < 0 || JS('int', '#', index) > length) {
      throw new RangeError.range(index, 0, this.length);
    }
    if (pattern is String) {
      String other = pattern;
      int otherLength = JS('int', '#.length', other);
      int endIndex = index + otherLength;
      if (endIndex > length) return false;
      return other == JS('String', r'#.substring(#, #)', this, index, endIndex);
    }
    return pattern.matchAsPrefix(this, index) != null;
  }

  @notNull
  String substring(@nullCheck int startIndex, [int _endIndex]) {
    var length = this.length;
    final endIndex = _endIndex ?? length;
    if (startIndex < 0) throw new RangeError.value(startIndex);
    if (startIndex > endIndex) throw new RangeError.value(startIndex);
    if (endIndex > length) throw new RangeError.value(endIndex);
    return JS('String', r'#.substring(#, #)', this, startIndex, endIndex);
  }

  @notNull
  String toLowerCase() {
    return JS('String', r'#.toLowerCase()', this);
  }

  @notNull
  String toUpperCase() {
    return JS('String', r'#.toUpperCase()', this);
  }

  // Characters with Whitespace property (Unicode 6.3).
  // 0009..000D    ; White_Space # Cc       <control-0009>..<control-000D>
  // 0020          ; White_Space # Zs       SPACE
  // 0085          ; White_Space # Cc       <control-0085>
  // 00A0          ; White_Space # Zs       NO-BREAK SPACE
  // 1680          ; White_Space # Zs       OGHAM SPACE MARK
  // 2000..200A    ; White_Space # Zs       EN QUAD..HAIR SPACE
  // 2028          ; White_Space # Zl       LINE SEPARATOR
  // 2029          ; White_Space # Zp       PARAGRAPH SEPARATOR
  // 202F          ; White_Space # Zs       NARROW NO-BREAK SPACE
  // 205F          ; White_Space # Zs       MEDIUM MATHEMATICAL SPACE
  // 3000          ; White_Space # Zs       IDEOGRAPHIC SPACE
  //
  // BOM: 0xFEFF
  @notNull
  static bool _isWhitespace(@notNull int codeUnit) {
    // Most codeUnits should be less than 256. Special case with a smaller
    // switch.
    if (codeUnit < 256) {
      switch (codeUnit) {
        case 0x09:
        case 0x0A:
        case 0x0B:
        case 0x0C:
        case 0x0D:
        case 0x20:
        case 0x85:
        case 0xA0:
          return true;
        default:
          return false;
      }
    }
    switch (codeUnit) {
      case 0x1680:
      case 0x2000:
      case 0x2001:
      case 0x2002:
      case 0x2003:
      case 0x2004:
      case 0x2005:
      case 0x2006:
      case 0x2007:
      case 0x2008:
      case 0x2009:
      case 0x200A:
      case 0x2028:
      case 0x2029:
      case 0x202F:
      case 0x205F:
      case 0x3000:
      case 0xFEFF:
        return true;
      default:
        return false;
    }
  }

  /// Finds the index of the first non-whitespace character, or the
  /// end of the string. Start looking at position [index].
  @notNull
  static int _skipLeadingWhitespace(String string, @nullCheck int index) {
    const int SPACE = 0x20;
    const int CARRIAGE_RETURN = 0x0D;
    var stringLength = string.length;
    while (index < stringLength) {
      int codeUnit = string.codeUnitAt(index);
      if (codeUnit != SPACE &&
          codeUnit != CARRIAGE_RETURN &&
          !_isWhitespace(codeUnit)) {
        break;
      }
      index++;
    }
    return index;
  }

  /// Finds the index after the last non-whitespace character, or 0.
  /// Start looking at position [index - 1].
  @notNull
  static int _skipTrailingWhitespace(String string, @nullCheck int index) {
    const int SPACE = 0x20;
    const int CARRIAGE_RETURN = 0x0D;
    while (index > 0) {
      int codeUnit = string.codeUnitAt(index - 1);
      if (codeUnit != SPACE &&
          codeUnit != CARRIAGE_RETURN &&
          !_isWhitespace(codeUnit)) {
        break;
      }
      index--;
    }
    return index;
  }

  // Dart2js can't use JavaScript trim directly,
  // because JavaScript does not trim
  // the NEXT LINE (NEL) character (0x85).
  @notNull
  String trim() {
    const int NEL = 0x85;

    // Start by doing JS trim. Then check if it leaves a NEL at
    // either end of the string.
    String result = JS('!', '#.trim()', this);
    final length = result.length;
    if (length == 0) return result;
    int firstCode = result.codeUnitAt(0);
    int startIndex = 0;
    if (firstCode == NEL) {
      startIndex = _skipLeadingWhitespace(result, 1);
      if (startIndex == length) return "";
    }

    int endIndex = length;
    // We know that there is at least one character that is non-whitespace.
    // Therefore we don't need to verify that endIndex > startIndex.
    int lastCode = result.codeUnitAt(endIndex - 1);
    if (lastCode == NEL) {
      endIndex = _skipTrailingWhitespace(result, endIndex - 1);
    }
    if (startIndex == 0 && endIndex == length) return result;
    return JS('String', r'#.substring(#, #)', result, startIndex, endIndex);
  }

  // Dart2js can't use JavaScript trimLeft directly,
  // because it is not in ES5, so not every browser implements it,
  // and because those that do will not trim the NEXT LINE character (0x85).
  @notNull
  String trimLeft() {
    const int NEL = 0x85;

    // Start by doing JS trim. Then check if it leaves a NEL at
    // the beginning of the string.
    String result;
    int startIndex = 0;
    if (JS('bool', 'typeof #.trimLeft != "undefined"', this)) {
      result = JS('String', '#.trimLeft()', this);
      if (result.length == 0) return result;
      int firstCode = result.codeUnitAt(0);
      if (firstCode == NEL) {
        startIndex = _skipLeadingWhitespace(result, 1);
      }
    } else {
      result = this;
      startIndex = _skipLeadingWhitespace(this, 0);
    }
    if (startIndex == 0) return result;
    if (startIndex == result.length) return "";
    return JS('String', r'#.substring(#)', result, startIndex);
  }

  // Dart2js can't use JavaScript trimRight directly,
  // because it is not in ES5 and because JavaScript does not trim
  // the NEXT LINE character (0x85).
  @notNull
  String trimRight() {
    const int NEL = 0x85;

    // Start by doing JS trim. Then check if it leaves a NEL or BOM at
    // the end of the string.
    String result;
    @notNull
    int endIndex = 0;
    // trimRight is implemented by Firefox and Chrome/Blink,
    // so use it if it is there.
    if (JS('bool', 'typeof #.trimRight != "undefined"', this)) {
      result = JS('String', '#.trimRight()', this);
      endIndex = result.length;
      if (endIndex == 0) return result;
      int lastCode = result.codeUnitAt(endIndex - 1);
      if (lastCode == NEL) {
        endIndex = _skipTrailingWhitespace(result, endIndex - 1);
      }
    } else {
      result = this;
      endIndex = _skipTrailingWhitespace(this, this.length);
    }

    if (endIndex == result.length) return result;
    if (endIndex == 0) return "";
    return JS('String', r'#.substring(#, #)', result, 0, endIndex);
  }

  @notNull
  String operator *(@nullCheck int times) {
    if (0 >= times) return '';
    if (times == 1 || this.length == 0) return this;
    if (times != JS('int', '# >>> 0', times)) {
      // times >= 2^32. We can't create a string that big.
      throw const OutOfMemoryError();
    }
    var result = '';
    String s = this;
    while (true) {
      if (times & 1 == 1) result = s + result;
      times = JS('int', '# >>> 1', times);
      if (times == 0) break;
      s += s;
    }
    return result;
  }

  @notNull
  String padLeft(@nullCheck int width, [String padding = ' ']) {
    int delta = width - this.length;
    if (delta <= 0) return this;
    return padding * delta + this;
  }

  @notNull
  String padRight(@nullCheck int width, [String padding = ' ']) {
    int delta = width - this.length;
    if (delta <= 0) return this;
    return this + padding * delta;
  }

  @notNull
  List<int> get codeUnits => new CodeUnits(this);

  @notNull
  Runes get runes => new Runes(this);

  @notNull
  int indexOf(@nullCheck Pattern pattern, [@nullCheck int start = 0]) {
    if (start < 0 || start > this.length) {
      throw new RangeError.range(start, 0, this.length);
    }
    if (pattern is String) {
      return stringIndexOfStringUnchecked(this, pattern, start);
    }
    if (pattern is JSSyntaxRegExp) {
      JSSyntaxRegExp re = pattern;
      Match match = firstMatchAfter(re, this, start);
      return (match == null) ? -1 : match.start;
    }
    var length = this.length;
    for (int i = start; i <= length; i++) {
      if (pattern.matchAsPrefix(this, i) != null) return i;
    }
    return -1;
  }

  @notNull
  int lastIndexOf(@nullCheck Pattern pattern, [int _start]) {
    var length = this.length;
    var start = _start ?? length;
    if (start < 0 || start > length) {
      throw new RangeError.range(start, 0, length);
    }
    if (pattern is String) {
      String other = pattern;
      if (start + other.length > length) {
        start = length - other.length;
      }
      return stringLastIndexOfUnchecked(this, other, start);
    }
    for (int i = start; i >= 0; i--) {
      if (pattern.matchAsPrefix(this, i) != null) return i;
    }
    return -1;
  }

  @notNull
  bool contains(@nullCheck Pattern other, [@nullCheck int startIndex = 0]) {
    if (startIndex < 0 || startIndex > this.length) {
      throw new RangeError.range(startIndex, 0, this.length);
    }
    return stringContainsUnchecked(this, other, startIndex);
  }

  @notNull
  bool get isEmpty => JS<int>('!', '#.length', this) == 0;

  @notNull
  bool get isNotEmpty => !isEmpty;

  @notNull
  int compareTo(@nullCheck String other) {
    return this == other ? 0 : JS('bool', r'# < #', this, other) ? -1 : 1;
  }

  // Note: if you change this, also change the function [S].
  @notNull
  String toString() => this;

  /**
   * This is the [Jenkins hash function][1] but using masking to keep
   * values in SMI range.
   *
   * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
   */
  @notNull
  int get hashCode {
    // TODO(ahe): This method shouldn't have to use JS. Update when our
    // optimizations are smarter.
    int hash = 0;
    int length = JS('!', '#.length', this);
    for (int i = 0; i < length; i++) {
      hash = 0x1fffffff & (hash + JS<int>('!', r'#.charCodeAt(#)', this, i));
      hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
      hash = JS('int', '# ^ (# >> 6)', hash, hash);
    }
    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
    hash = JS('int', '# ^ (# >> 11)', hash, hash);
    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
  }

  @notNull
  Type get runtimeType => String;

  @notNull
  final int length;

  @notNull
  String operator [](@nullCheck int index) {
    if (index >= JS('int', '#.length', this) || index < 0) {
      throw diagnoseIndexError(this, index);
    }
    return JS('String', '#[#]', this, index);
  }
}
