// 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 _js_helper;

int stringIndexOfStringUnchecked(
    String receiver, String other, int startIndex) {
  return JS('int', '#.indexOf(#, #)', receiver, other, startIndex);
}

String substring1Unchecked(String receiver, int startIndex) {
  return JS('String', '#.substring(#)', receiver, startIndex);
}

String substring2Unchecked(String receiver, int startIndex, int endIndex) {
  return JS('String', '#.substring(#, #)', receiver, startIndex, endIndex);
}

bool stringContainsStringUnchecked(
    String receiver, String other, int startIndex) {
  return stringIndexOfStringUnchecked(receiver, other, startIndex) >= 0;
}

List<String> stringSplitUnchecked(
    String receiver,
    /* String | JavaScript RegExp */
    pattern) {
  return new JSArray<String>.markGrowable(JS(
      'returns:JSExtendableArray;new:true', '#.split(#)', receiver, pattern));
}

class StringMatch implements Match {
  const StringMatch(int this.start, String this.input, String this.pattern);

  int get end => start + pattern.length;
  String operator [](int g) => group(g);
  int get groupCount => 0;

  String group(int group_) {
    if (group_ != 0) {
      throw new RangeError.value(group_);
    }
    return pattern;
  }

  List<String> groups(List<int> groups_) {
    List<String> result = <String>[];
    for (int g in groups_) {
      result.add(group(g));
    }
    return result;
  }

  final int start;
  final String input;
  final String pattern;
}

Iterable<Match> allMatchesInStringUnchecked(
    String pattern, String string, int startIndex) {
  return new _StringAllMatchesIterable(string, pattern, startIndex);
}

class _StringAllMatchesIterable extends Iterable<Match> {
  final String _input;
  final String _pattern;
  final int _index;

  _StringAllMatchesIterable(this._input, this._pattern, this._index);

  Iterator<Match> get iterator =>
      new _StringAllMatchesIterator(_input, _pattern, _index);

  Match get first {
    int index = stringIndexOfStringUnchecked(_input, _pattern, _index);
    if (index >= 0) {
      return new StringMatch(index, _input, _pattern);
    }
    throw IterableElementError.noElement();
  }
}

class _StringAllMatchesIterator implements Iterator<Match> {
  final String _input;
  final String _pattern;
  int _index;
  Match? _current;

  _StringAllMatchesIterator(this._input, this._pattern, this._index);

  bool moveNext() {
    if (_index + _pattern.length > _input.length) {
      _current = null;
      return false;
    }
    int index = stringIndexOfStringUnchecked(_input, _pattern, _index);
    if (index < 0) {
      _index = _input.length + 1;
      _current = null;
      return false;
    }
    int end = index + _pattern.length;
    _current = new StringMatch(index, _input, _pattern);
    // Empty match, don't start at same location again.
    if (end == _index) end++;
    _index = end;
    return true;
  }

  Match get current => _current!;
}

bool stringContainsUnchecked(String receiver, Pattern other, int startIndex) {
  if (other is String) {
    return stringContainsStringUnchecked(receiver, other, startIndex);
  } else if (other is JSSyntaxRegExp) {
    return other.hasMatch(receiver.substring(startIndex));
  } else {
    var substr = receiver.substring(startIndex);
    return other.allMatches(substr).isNotEmpty;
  }
}

String stringReplaceJS(String receiver, jsRegExp, String replacement) {
  return JS('String', r'#.replace(#, #)', receiver, jsRegExp,
      escapeReplacement(replacement));
}

String escapeReplacement(String replacement) {
  // The JavaScript `String.prototype.replace` method recognizes replacement
  // patterns in the replacement string. Dart does not have that behavior, so
  // the replacement patterns need to be escaped.

  // `String.prototype.replace` tends to be slower when there are replacement
  // patterns, and the escaping itself uses replacement patterns, so it is
  // worthwhile checking for `$` first.
  if (stringContainsStringUnchecked(replacement, r'$', 0)) {
    return JS('String', r'#.replace(/\$/g, "$$$$")', replacement);
  }
  return replacement;
}

String stringReplaceFirstRE(String receiver, JSSyntaxRegExp regexp,
    String replacement, int startIndex) {
  var match = regexp._execGlobal(receiver, startIndex);
  if (match == null) return receiver;
  var start = match.start;
  var end = match.end;
  return stringReplaceRangeUnchecked(receiver, start, end, replacement);
}

/// Returns a string for a RegExp pattern that matches [string]. This is done by
/// escaping all RegExp metacharacters.
quoteStringForRegExp(string) {
  // We test and replace essentially the same RegExp because replacement when
  // there are replacement patterns is slow enough to be worth avoiding.
  if (JS('bool', r'/[[\]{}()*+?.\\^$|]/.test(#)', string)) {
    return JS('String', r'#.replace(/[[\]{}()*+?.\\^$|]/g, "\\$&")', string);
  }
  return string;
}

String stringReplaceAllUnchecked(
    String receiver, Pattern pattern, String replacement) {
  checkString(replacement);
  if (pattern is String) {
    return stringReplaceAllUncheckedString(receiver, pattern, replacement);
  }

  if (pattern is JSSyntaxRegExp) {
    var re = regExpGetGlobalNative(pattern);
    return stringReplaceJS(receiver, re, replacement);
  }

  return stringReplaceAllGeneral(receiver, pattern, replacement);
}

String stringReplaceAllGeneral(
    String receiver, Pattern pattern, String replacement) {
  checkNull(pattern);
  int startIndex = 0;
  StringBuffer result = StringBuffer();
  for (Match match in pattern.allMatches(receiver)) {
    result.write(substring2Unchecked(receiver, startIndex, match.start));
    result.write(replacement);
    startIndex = match.end;
  }
  result.write(substring1Unchecked(receiver, startIndex));
  return result.toString();
}

/// Replaces all non-overlapping occurences of [pattern] in [receiver] with
/// [replacement].  This should be replace with
/// (String.prototype.replaceAll)[https://github.com/tc39/proposal-string-replace-all]
/// when available.
String stringReplaceAllUncheckedString(
    String receiver, String pattern, String replacement) {
  if (pattern == "") {
    if (receiver == "") {
      return JS('String', '#', replacement); // help type inference.
    }
    StringBuffer result = new StringBuffer('');
    int length = receiver.length;
    result.write(replacement);
    for (int i = 0; i < length; i++) {
      result.write(receiver[i]);
      result.write(replacement);
    }
    return result.toString();
  }

  if (!const bool.fromEnvironment(
      'dart2js.testing.String.replaceAll.force.regexp')) {
    // First check for no match.
    int index = stringIndexOfStringUnchecked(receiver, pattern, 0);
    if (index < 0) return receiver;

    // The fastest approach in general is to replace with a global RegExp, but
    // this requires the receiver string to be long enough to amortize the cost
    // of creating the RegExp, and the replacement to have no '$' patterns,
    // which tend to make `String.prototype.replace` much slower. In these
    // cases, using split-join usually wins.
    if (receiver.length < 500 ||
        stringContainsStringUnchecked(replacement, r'$', 0)) {
      return stringReplaceAllUsingSplitJoin(receiver, pattern, replacement);
    }
  }
  var quoted = quoteStringForRegExp(pattern);
  var replacer = JS('', "new RegExp(#, 'g')", quoted);
  return stringReplaceJS(receiver, replacer, replacement);
}

String stringReplaceAllUsingSplitJoin(
    String receiver, String pattern, String replacement) {
  return JS('String', '#.split(#).join(#)', receiver, pattern, replacement);
}

String _matchString(Match match) => match[0]!;
String _stringIdentity(String string) => string;

String stringReplaceAllFuncUnchecked(String receiver, Pattern pattern,
    String Function(Match)? onMatch, String Function(String)? onNonMatch) {
  onMatch ??= _matchString;
  onNonMatch ??= _stringIdentity;
  if (pattern is String) {
    return stringReplaceAllStringFuncUnchecked(
        receiver, pattern, onMatch, onNonMatch);
  }
  // Placing the Pattern test here is indistinguishable from placing it at the
  // top of the method but it saves an extra check on the `pattern is String`
  // path.
  if (pattern is! Pattern) {
    throw new ArgumentError.value(pattern, 'pattern', 'is not a Pattern');
  }
  StringBuffer buffer = new StringBuffer('');
  int startIndex = 0;
  for (Match match in pattern.allMatches(receiver)) {
    buffer.write(onNonMatch(receiver.substring(startIndex, match.start)));
    buffer.write(onMatch(match));
    startIndex = match.end;
  }
  buffer.write(onNonMatch(receiver.substring(startIndex)));
  return buffer.toString();
}

String stringReplaceAllEmptyFuncUnchecked(String receiver,
    String Function(Match) onMatch, String Function(String) onNonMatch) {
  // Pattern is the empty string.
  StringBuffer buffer = StringBuffer();
  int length = receiver.length;
  int i = 0;
  buffer.write(onNonMatch(""));
  while (i < length) {
    buffer.write(onMatch(new StringMatch(i, receiver, "")));
    // Special case to avoid splitting a surrogate pair.
    int code = receiver.codeUnitAt(i);
    if ((code & ~0x3FF) == 0xD800 && length > i + 1) {
      // Leading surrogate;
      code = receiver.codeUnitAt(i + 1);
      if ((code & ~0x3FF) == 0xDC00) {
        // Matching trailing surrogate.
        buffer.write(onNonMatch(receiver.substring(i, i + 2)));
        i += 2;
        continue;
      }
    }
    buffer.write(onNonMatch(receiver[i]));
    i++;
  }
  buffer.write(onMatch(new StringMatch(i, receiver, "")));
  buffer.write(onNonMatch(""));
  return buffer.toString();
}

String stringReplaceAllStringFuncUnchecked(String receiver, String pattern,
    String Function(Match) onMatch, String Function(String) onNonMatch) {
  int patternLength = pattern.length;
  if (patternLength == 0) {
    return stringReplaceAllEmptyFuncUnchecked(receiver, onMatch, onNonMatch);
  }
  int length = receiver.length;
  StringBuffer buffer = new StringBuffer('');
  int startIndex = 0;
  while (startIndex < length) {
    int position = stringIndexOfStringUnchecked(receiver, pattern, startIndex);
    if (position == -1) {
      break;
    }
    buffer.write(onNonMatch(receiver.substring(startIndex, position)));
    buffer.write(onMatch(new StringMatch(position, receiver, pattern)));
    startIndex = position + patternLength;
  }
  buffer.write(onNonMatch(receiver.substring(startIndex)));
  return buffer.toString();
}

String stringReplaceFirstUnchecked(
    String receiver, Pattern pattern, String replacement, int startIndex) {
  if (pattern is String) {
    int index = stringIndexOfStringUnchecked(receiver, pattern, startIndex);
    if (index < 0) return receiver;
    int end = index + pattern.length;
    return stringReplaceRangeUnchecked(receiver, index, end, replacement);
  }
  if (pattern is JSSyntaxRegExp) {
    return startIndex == 0
        ? stringReplaceJS(receiver, regExpGetNative(pattern), replacement)
        : stringReplaceFirstRE(receiver, pattern, replacement, startIndex);
  }
  checkNull(pattern);
  Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator;
  if (!matches.moveNext()) return receiver;
  Match match = matches.current;
  return receiver.replaceRange(match.start, match.end, replacement);
}

String stringReplaceFirstMappedUnchecked(String receiver, Pattern pattern,
    String Function(Match) replace, int startIndex) {
  Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator;
  if (!matches.moveNext()) return receiver;
  Match match = matches.current;
  String replacement = "${replace(match)}";
  return receiver.replaceRange(match.start, match.end, replacement);
}

String stringReplaceRangeUnchecked(
    String receiver, int start, int end, String replacement) {
  var prefix = JS('String', '#.substring(0, #)', receiver, start);
  var suffix = JS('String', '#.substring(#)', receiver, end);
  return "$prefix$replacement$suffix";
}
