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

import 'dart:_error_utils';
import 'dart:_internal';
import 'dart:_js_helper' as js;
import 'dart:_js_types';
import 'dart:_object_helper';
import 'dart:_string_helper';
import 'dart:_string' show jsStringFromCharCodeArray;
import 'dart:_wasm';
import 'dart:js_interop';

abstract class StringUncheckedOperationsBase {
  int _codeUnitAtUnchecked(int index);
  String _substringUnchecked(int start, int end);
}

extension StringUncheckedOperations on String {
  @pragma('wasm:prefer-inline')
  int codeUnitAtUnchecked(int index) =>
      unsafeCast<StringUncheckedOperationsBase>(
        this,
      )._codeUnitAtUnchecked(index);

  @pragma('wasm:prefer-inline')
  String substringUnchecked(int start, int end) =>
      unsafeCast<StringUncheckedOperationsBase>(
        this,
      )._substringUnchecked(start, end);
}

final class JSStringImpl implements String, StringUncheckedOperationsBase {
  final WasmExternRef? _ref;

  JSStringImpl(this._ref);

  @pragma("wasm:prefer-inline")
  static String? box(WasmExternRef? ref) =>
      js.isDartNull(ref) ? null : JSStringImpl(ref);

  @override
  @pragma("wasm:prefer-inline")
  int get length => _jsLength(toExternRef);

  @override
  @pragma("wasm:prefer-inline")
  bool get isEmpty => length == 0;

  @override
  @pragma("wasm:prefer-inline")
  bool get isNotEmpty => !isEmpty;

  @pragma("wasm:entry-point")
  static String _interpolate(WasmArray<Object?> values) {
    final valuesLength = values.length;
    String result = '';
    for (int i = 0; i < valuesLength; i++) {
      result = result + values[i].toString();
    }
    return result;
  }

  @pragma("wasm:entry-point", "call")
  static String _interpolate1(Object? value) {
    return value is String ? value : value.toString();
  }

  @pragma("wasm:entry-point", "call")
  static String _interpolate2(Object? value1, Object? value2) {
    final String string1 = value1 is String ? value1 : value1.toString();
    final String string2 = value2 is String ? value2 : value2.toString();
    return JSStringImpl(
      _jsStringConcatImport(
        unsafeCast<JSStringImpl>(string1).toExternRef,
        unsafeCast<JSStringImpl>(string2).toExternRef,
      ),
    );
  }

  @pragma("wasm:entry-point", "call")
  static String _interpolate3(Object? value1, Object? value2, Object? value3) {
    final String string1 = value1 is String ? value1 : value1.toString();
    final String string2 = value2 is String ? value2 : value2.toString();
    final String string3 = value3 is String ? value3 : value3.toString();
    return JSStringImpl(
      _jsStringConcatImport(
        _jsStringConcatImport(
          unsafeCast<JSStringImpl>(string1).toExternRef,
          unsafeCast<JSStringImpl>(string2).toExternRef,
        ),
        unsafeCast<JSStringImpl>(string3).toExternRef,
      ),
    );
  }

  @pragma("wasm:entry-point", "call")
  static String _interpolate4(
    Object? value1,
    Object? value2,
    Object? value3,
    Object? value4,
  ) {
    final String string1 = value1 is String ? value1 : value1.toString();
    final String string2 = value2 is String ? value2 : value2.toString();
    final String string3 = value3 is String ? value3 : value3.toString();
    final String string4 = value4 is String ? value4 : value4.toString();
    return JSStringImpl(
      _jsStringConcatImport(
        _jsStringConcatImport(
          unsafeCast<JSStringImpl>(string1).toExternRef,
          unsafeCast<JSStringImpl>(string2).toExternRef,
        ),
        _jsStringConcatImport(
          unsafeCast<JSStringImpl>(string3).toExternRef,
          unsafeCast<JSStringImpl>(string4).toExternRef,
        ),
      ),
    );
  }

  static const _codeUnitsCacheSize = 512;
  @pragma('wasm:initialize-at-startup')
  static final _codeUnitsCache = WasmArray<WasmI16>(_codeUnitsCacheSize);
  static JSStringImpl fromAsciiBytes(
    WasmArray<WasmI8> source,
    int start,
    int end,
  ) {
    final length = end - start;
    if (length <= _codeUnitsCacheSize) {
      final array = _codeUnitsCache;
      for (int i = 0; i < length; ++i) {
        array.write(i, source.readUnsigned(start++));
      }
      return fromCharCodeArray(array, 0, length);
    }
    final array = WasmArray<WasmI16>(length);
    for (int i = 0; i < length; ++i) {
      array.write(i, source.readUnsigned(start++));
    }
    return fromCharCodeArray(array, 0, length);
  }

  static JSStringImpl fromCharCodeArray(
    WasmArray<WasmI16> source,
    int start,
    int end,
  ) {
    return JSStringImpl(
      jsStringFromCharCodeArray(source, start.toWasmI32(), end.toWasmI32()),
    );
  }

  @pragma("wasm:initialize-at-startup")
  static final _stringFromCodePointBuffer = WasmArray<WasmI16>(2);

  static JSStringImpl fromCharCode(int charCode) {
    final array = _stringFromCodePointBuffer;
    array.write(0, charCode);
    return JSStringImpl.fromCharCodeArray(array, 0, 1);
  }

  static JSStringImpl fromCodePoint(int codePoint) {
    final array = _stringFromCodePointBuffer;
    if (codePoint <= 0xffff) {
      array.write(0, codePoint);
      return JSStringImpl.fromCharCodeArray(array, 0, 1);
    }
    final low = 0xDC00 | (codePoint & 0x3ff);
    final high = 0xD7C0 + (codePoint >> 10);
    array.write(0, high);
    array.write(1, low);
    return JSStringImpl.fromCharCodeArray(array, 0, 2);
  }

  @override
  @pragma("wasm:prefer-inline")
  int codeUnitAt(int index) {
    final length = this.length;
    IndexErrorUtils.checkIndex(index, length);
    return _codeUnitAtUnchecked(index);
  }

  @override
  @pragma("wasm:prefer-inline")
  int _codeUnitAtUnchecked(int index) {
    return jsCharCodeAt(toExternRef, index);
  }

  @override
  Iterable<Match> allMatches(String string, [int start = 0]) {
    final stringLength = string.length;
    RangeErrorUtils.checkValueBetweenZeroAndPositiveMax(start, stringLength);
    return StringAllMatchesIterable(string, this, start);
  }

  @override
  Match? matchAsPrefix(String string, [int start = 0]) {
    final stringLength = string.length;
    RangeErrorUtils.checkValueBetweenZeroAndPositiveMax(start, stringLength);
    final length = this.length;
    if (start + length > stringLength) return null;
    // TODO(lrn): See if this can be optimized.
    for (int i = 0; i < length; i++) {
      if (string.codeUnitAt(start + i) != codeUnitAt(i)) {
        return null;
      }
    }
    return StringMatch(start, string, this);
  }

  @override
  @pragma('dyn-module:callable')
  String operator +(String other) {
    return JSStringImpl(
      _jsStringConcatImport(
        toExternRef,
        unsafeCast<JSStringImpl>(other).toExternRef,
      ),
    );
  }

  @override
  bool endsWith(String other) {
    final otherLength = other.length;
    final length = this.length;
    if (otherLength > length) return false;
    return other == _substringUnchecked(length - otherLength, length);
  }

  @override
  String replaceAll(Pattern from, String to) {
    if (from is String) {
      if (from.isEmpty) {
        if (isEmpty) return to;
        StringBuffer result = StringBuffer();
        result.write(to);
        final length = this.length;
        for (int i = 0; i < length; i++) {
          result.write(this[i]);
          result.write(to);
        }
        return result.toString();
      }
      return _jsStringReplaceAll(
        toExternRef,
        unsafeCast<JSStringImpl>(from).toExternRef,
        to.toExternRef,
      );
    }

    if (from is js.JSSyntaxRegExp) {
      return _jsStringReplace(
        toExternRef,
        (js.regExpGetGlobalNative(from) as js.JSValue).toExternRef,
        to.toExternRef,
      );
    } else {
      int startIndex = 0;
      StringBuffer result = StringBuffer();
      for (Match match in from.allMatches(this)) {
        result.write(substring(startIndex, match.start));
        result.write(to);
        startIndex = match.end;
      }
      result.write(substring(startIndex));
      return result.toString();
    }
  }

  @override
  String replaceAllMapped(Pattern from, String Function(Match) convert) {
    return splitMapJoin(from, onMatch: convert);
  }

  @override
  String splitMapJoin(
    Pattern from, {
    String Function(Match)? onMatch,
    String Function(String)? onNonMatch,
  }) {
    if (onMatch == null) onMatch = _matchString;
    if (onNonMatch == null) onNonMatch = _stringIdentity;
    if (from is String) {
      final patternLength = from.length;
      if (patternLength == 0) {
        // Pattern is the empty string.
        StringBuffer buffer = StringBuffer();
        int i = 0;
        buffer.write(onNonMatch(""));
        final length = this.length;
        while (i < length) {
          buffer.write(onMatch(StringMatch(i, this, "")));
          // Special case to avoid splitting a surrogate pair.
          int code = codeUnitAt(i);
          if ((code & ~0x3FF) == 0xD800 && length > i + 1) {
            // Leading surrogate;
            code = codeUnitAt(i + 1);
            if ((code & ~0x3FF) == 0xDC00) {
              // Matching trailing surrogate.
              buffer.write(onNonMatch(substring(i, i + 2)));
              i += 2;
              continue;
            }
          }
          buffer.write(onNonMatch(this[i]));
          i++;
        }
        buffer.write(onMatch(StringMatch(i, this, "")));
        buffer.write(onNonMatch(""));
        return buffer.toString();
      }
      StringBuffer buffer = StringBuffer();
      int startIndex = 0;
      final length = this.length;
      while (startIndex < length) {
        int position = indexOf(from, startIndex);
        if (position == -1) {
          break;
        }
        buffer.write(onNonMatch(substring(startIndex, position)));
        buffer.write(onMatch(StringMatch(position, this, from)));
        startIndex = position + patternLength;
      }
      buffer.write(onNonMatch(substring(startIndex)));
      return buffer.toString();
    }
    StringBuffer buffer = StringBuffer();
    int startIndex = 0;
    for (Match match in from.allMatches(this)) {
      buffer.write(onNonMatch(substring(startIndex, match.start)));
      buffer.write(onMatch(match));
      startIndex = match.end;
    }
    buffer.write(onNonMatch(substring(startIndex)));
    return buffer.toString();
  }

  String _replaceRange(int start, int end, String replacement) {
    String prefix = substring(0, start);
    String suffix = substring(end);
    return "$prefix$replacement$suffix";
  }

  String _replaceFirstRE(
    js.JSSyntaxRegExp regexp,
    String replacement,
    int startIndex,
  ) {
    final match = js.regExpExecGlobal(regexp, this.toJS, startIndex);
    if (match == null) return this;
    final start = match.start;
    final end = match.end;
    return _replaceRange(start, end, replacement);
  }

  @override
  String replaceFirst(Pattern from, String to, [int startIndex = 0]) {
    RangeErrorUtils.checkValueBetweenZeroAndPositiveMax(startIndex, length);
    if (from is String) {
      int index = indexOf(from, startIndex);
      if (index < 0) return this;
      int end = index + from.length;
      return _replaceRange(index, end, to);
    }
    if (from is js.JSSyntaxRegExp) {
      return startIndex == 0
          ? _jsStringReplace(
              toExternRef,
              (js.regExpGetNative(from) as js.JSValue).toExternRef,
              to.toExternRef,
            )
          : _replaceFirstRE(from, to, startIndex);
    }
    Iterator<Match> matches = from.allMatches(this, startIndex).iterator;
    if (!matches.moveNext()) return this;
    Match match = matches.current;
    return replaceRange(match.start, match.end, to);
  }

  @override
  String replaceFirstMapped(
    Pattern from,
    String replace(Match match), [
    int startIndex = 0,
  ]) {
    RangeErrorUtils.checkValueBetweenZeroAndPositiveMax(startIndex, length);
    Iterator<Match> matches = from.allMatches(this, startIndex).iterator;
    if (!matches.moveNext()) return this;
    Match match = matches.current;
    String replacement = "${replace(match)}";
    return replaceRange(match.start, match.end, replacement);
  }

  @override
  List<String> split(Pattern pattern) {
    if (pattern is JSStringImpl) {
      return _jsStringSplitToDart(toExternRef, pattern.toExternRef);
    } else if (pattern is String) {
      return _jsStringSplitToDart(toExternRef, pattern.toJS.toExternRef);
    } else if (pattern is js.JSSyntaxRegExp &&
        js.regExpCaptureCount(pattern) == 0) {
      final re = js.regExpGetNative(pattern);
      return _jsStringSplitToDart(toExternRef, (re as js.JSValue).toExternRef);
    } else {
      final 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)) {
        int matchStart = match.start;
        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(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(substring(start));
      }
      return result;
    }
  }

  @override
  String replaceRange(int start, int? end, String replacement) {
    end ??= length;
    RangeErrorUtils.checkValidRange(start, end, length);
    return _replaceRange(start, end, replacement);
  }

  @override
  bool startsWith(Pattern pattern, [int index = 0]) {
    RangeErrorUtils.checkValueBetweenZeroAndPositiveMax(index, length);
    if (pattern is String) {
      final patternLength = pattern.length;
      final endIndex = index + patternLength;
      if (endIndex > length) return false;
      return pattern == substring(index, endIndex);
    }
    return pattern.matchAsPrefix(this, index) != null;
  }

  @override
  String substring(int start, [int? end]) {
    end ??= length;
    RangeErrorUtils.checkValidRange(start, end, length);
    if (start == end) return "";
    return _substringUnchecked(start, end);
  }

  @override
  @pragma('wasm:prefer-inline')
  String _substringUnchecked(int start, int end) =>
      JSStringImpl(_jsSubstring(toExternRef, start, end));

  @override
  String toLowerCase() {
    final thisRef = toExternRef;
    final lowerCaseRef = _jsStringToLowerCase(thisRef);
    return _jsIdentical(thisRef, lowerCaseRef)
        ? this
        : JSStringImpl(lowerCaseRef);
  }

  @override
  String toUpperCase() {
    final thisRef = toExternRef;
    final upperCaseRef = _jsStringToUpperCase(thisRef);
    return _jsIdentical(thisRef, upperCaseRef)
        ? this
        : JSStringImpl(upperCaseRef);
  }

  // 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
  static bool _isWhitespace(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;
    }
  }

  static const int spaceCodeUnit = 0x20;
  static const int carriageReturnCodeUnit = 0x0D;
  static const int nelCodeUnit = 0x85;

  /// Finds the index of the first non-whitespace character, or the
  /// end of the string. Start looking at position [index].
  static int _skipLeadingWhitespace(JSStringImpl string, int index) {
    final stringLength = string.length;
    while (index < stringLength) {
      int codeUnit = string._codeUnitAtUnchecked(index);
      if (codeUnit != spaceCodeUnit &&
          codeUnit != carriageReturnCodeUnit &&
          !_isWhitespace(codeUnit)) {
        break;
      }
      index++;
    }
    return index;
  }

  /// Finds the index after the last non-whitespace character, or 0.
  /// Start looking at position [index - 1].
  static int _skipTrailingWhitespace(JSStringImpl string, int index) {
    while (index > 0) {
      int codeUnit = string._codeUnitAtUnchecked(index - 1);
      if (codeUnit != spaceCodeUnit &&
          codeUnit != carriageReturnCodeUnit &&
          !_isWhitespace(codeUnit)) {
        break;
      }
      index--;
    }
    return index;
  }

  // dart2wasm can't use JavaScript trim directly, because JavaScript does not
  // trim the NEXT LINE (NEL) character (0x85).
  @override
  String trim() {
    final length = this.length;
    if (length == 0) return this;

    // Start by doing JS trim. Then check if it leaves a NEL at either end of
    // the string.
    final result = JSStringImpl(_jsStringTrim(toExternRef));
    final resultLength = result.length;
    if (resultLength == 0) return result;

    // Check NEL on the left.
    final int firstCode = result._codeUnitAtUnchecked(0);
    int startIndex = 0;
    if (firstCode == nelCodeUnit) {
      startIndex = _skipLeadingWhitespace(result, 1);
      if (startIndex == resultLength) return "";
    }

    // Check NEL on the right.
    int endIndex = resultLength;
    // We know that there is at least one character that is non-whitespace.
    // Therefore we don't need to verify that endIndex > startIndex.
    final int lastCode = result.codeUnitAt(endIndex - 1);
    if (lastCode == nelCodeUnit) {
      endIndex = _skipTrailingWhitespace(result, endIndex - 1);
    }

    if (startIndex == 0 && endIndex == resultLength) {
      return length == resultLength ? this : result;
    }

    return result.substring(startIndex, endIndex);
  }

  // dart2wasm can't use JavaScript trimLeft directly because it does not trim
  // the NEXT LINE (NEL) character (0x85).
  @override
  String trimLeft() {
    final length = this.length;
    if (length == 0) return this;

    // Start by doing JS trim. Then check if it leaves a NEL at the beginning
    // of the string.
    int startIndex = 0;
    final result = JSStringImpl(_jsStringTrimLeft(toExternRef));
    final resultLength = result.length;
    if (resultLength == 0) return result;

    // Check NEL.
    int firstCode = result._codeUnitAtUnchecked(0);
    if (firstCode == nelCodeUnit) {
      startIndex = _skipLeadingWhitespace(result, 1);
    }

    if (startIndex == 0) {
      return resultLength == length ? this : result;
    }

    return result.substring(startIndex);
  }

  // dart2wasm can't use JavaScript trimRight directly because it does not trim
  // the NEXT LINE (NEL) character (0x85).
  @override
  String trimRight() {
    final length = this.length;
    if (length == 0) return this;

    // Start by doing JS trim. Then check if it leaves a NEL at the end of the
    // string.
    final result = JSStringImpl(_jsStringTrimRight(toExternRef));
    final resultLength = result.length;
    if (resultLength == 0) return result;

    int endIndex = resultLength;
    int lastCode = result.codeUnitAt(endIndex - 1);
    if (lastCode == nelCodeUnit) {
      endIndex = _skipTrailingWhitespace(result, endIndex - 1);
    }

    if (endIndex == resultLength) {
      return resultLength == length ? this : result;
    }

    return result.substring(0, endIndex);
  }

  @override
  String operator *(int times) {
    if (0 >= times) return '';
    if (times == 1 || length == 0) return this;
    if (times & 0x7fffffff != times) {
      throw Exception(
        'The implementation cannot handle very large operands (was: $times).',
      );
    }
    return JSStringImpl(_jsStringRepeat(toExternRef, times));
  }

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

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

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

  @override
  Runes get runes => Runes(this);

  @override
  int indexOf(Pattern pattern, [int start = 0]) {
    final length = this.length;
    RangeErrorUtils.checkValueBetweenZeroAndPositiveMax(start, length);
    if (pattern is JSStringImpl) {
      return _jsStringIndexOf(toExternRef, pattern.toExternRef, start);
    } else if (pattern is String) {
      return _jsStringIndexOf(toExternRef, pattern.toJS.toExternRef, start);
    } else if (pattern is js.JSSyntaxRegExp) {
      Match? match = js.firstMatchAfter(pattern, this.toJS, start);
      return (match == null) ? -1 : match.start;
    } else {
      for (int i = start; i <= length; i++) {
        if (pattern.matchAsPrefix(this, i) != null) return i;
      }
      return -1;
    }
  }

  @override
  int lastIndexOf(Pattern pattern, [int? start]) {
    final length = this.length;
    if (start == null) {
      start = length;
    } else {
      RangeErrorUtils.checkValueBetweenZeroAndPositiveMax(start, length);
    }
    if (pattern is JSStringImpl) {
      if (start + pattern.length > length) {
        start = length - pattern.length;
      }
      return _jsStringLastIndexOf(toExternRef, pattern.toExternRef, start);
    } else if (pattern is String) {
      if (start + pattern.length > length) {
        start = length - pattern.length;
      }
      return _jsStringLastIndexOf(toExternRef, pattern.toJS.toExternRef, start);
    }
    for (int i = start; i >= 0; i--) {
      if (pattern.matchAsPrefix(this, i) != null) return i;
    }
    return -1;
  }

  @override
  bool contains(Pattern other, [int startIndex = 0]) {
    final length = this.length;
    RangeErrorUtils.checkValueBetweenZeroAndPositiveMax(startIndex, length);
    if (other is String) {
      return indexOf(other, startIndex) >= 0;
    } else if (other is js.JSSyntaxRegExp) {
      return other.hasMatch(substring(startIndex));
    } else {
      return other.allMatches(substring(startIndex)).isNotEmpty;
    }
  }

  @override
  int get hashCode {
    int hash = getIdentityHashField(this);
    if (hash != 0) return hash;
    hash = _computeHashCode();
    setIdentityHashField(this, hash);
    return hash;
  }

  /// This must be kept in sync with `StringBase.hashCode` in string_patch.dart.
  int _computeHashCode() {
    int hash = 0;
    final length = this.length;
    for (int i = 0; i < length; i++) {
      hash = stringCombineHashes(hash, _codeUnitAtUnchecked(i));
    }
    return stringFinalizeHash(hash);
  }

  @override
  @pragma("wasm:prefer-inline")
  String operator [](int index) {
    IndexErrorUtils.checkIndex(index, length);
    return JSStringImpl.fromCharCode(_codeUnitAtUnchecked(index));
  }

  @override
  @pragma('wasm:prefer-inline')
  bool operator ==(Object other) =>
      other is JSStringImpl && _jsEquals(toExternRef, other.toExternRef);

  @override
  @pragma('wasm:prefer-inline')
  int compareTo(String other) =>
      _jsCompare(toExternRef, unsafeCast<JSStringImpl>(other).toExternRef);

  @override
  String toString() => this;

  int firstNonWhitespace() {
    final length = this.length;
    int first = 0;
    for (; first < length; first++) {
      if (!_isWhitespace(_codeUnitAtUnchecked(first))) {
        break;
      }
    }
    return first;
  }

  int lastNonWhitespace() {
    int last = length - 1;
    for (; last >= 0; last--) {
      if (!_isWhitespace(_codeUnitAtUnchecked(last))) {
        break;
      }
    }
    return last;
  }
}

extension JSStringImplExt on JSStringImpl {
  @pragma("wasm:prefer-inline")
  WasmExternRef? get toExternRef => _ref;
}

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

String _stringIdentity(String string) => string;

// NOTE: The [replacement] does not need special escaping it will be used
// as-is (due to passing `() => r` to the JS `replaceAll()` call)
JSStringImpl _jsStringReplaceAll(
  WasmExternRef? string,
  WasmExternRef? pattern,
  WasmExternRef? replacement,
) => JSStringImpl(
  js.JS<WasmExternRef?>(
    '(o, p, r) => o.replaceAll(p, () => r)',
    string,
    pattern,
    replacement,
  ),
);

// NOTE: The [replacement] does not need special escaping it will be used
// as-is (due to passing `() => r` to the JS `replaceAll()` call)
String _jsStringReplace(
  WasmExternRef? string,
  WasmExternRef? pattern,
  WasmExternRef? replacement,
) => JSStringImpl(
  js.JS<WasmExternRef?>(
    '(o, p, r) => o.replace(p, () => r)',
    string,
    pattern,
    replacement,
  ),
);

WasmExternRef? _jsStringToLowerCase(WasmExternRef? string) =>
    // Note: Special cased in V8 to be fast as `F.p.c.b`.
    // Do not change to `s => s.toLowerCase()`!
    js.JS<WasmExternRef?>(
      'Function.prototype.call.bind(String.prototype.toLowerCase)',
      string,
    );

WasmExternRef? _jsStringToUpperCase(WasmExternRef? string) =>
    js.JS<WasmExternRef?>('s => s.toUpperCase()', string);

WasmExternRef? _jsStringTrim(WasmExternRef? string) =>
    js.JS<WasmExternRef?>('s => s.trim()', string);

WasmExternRef? _jsStringTrimLeft(WasmExternRef? string) =>
    js.JS<WasmExternRef?>('s => s.trimLeft()', string);

WasmExternRef? _jsStringTrimRight(WasmExternRef? string) =>
    js.JS<WasmExternRef?>('s => s.trimRight()', string);

@pragma("wasm:prefer-inline")
WasmExternRef? _jsStringRepeat(WasmExternRef? string, int times) =>
    js.JS<WasmExternRef?>(
      '(string, times) => string.repeat(times)',
      string,
      times.toWasmI32(),
    );

@pragma("wasm:prefer-inline")
int _jsStringIndexOf(
  WasmExternRef? string,
  WasmExternRef? pattern,
  int startIndex,
) =>
    // Note: Special cased in V8 to be fast as `F.p.c.b`.
    // Do not change to `(s, p, i) => s.indexOf(p, i)`!
    js
        .JS<double>(
          'Function.prototype.call.bind(String.prototype.indexOf)',
          string,
          pattern,
          startIndex.toWasmI32(),
        )
        .toInt();

@pragma("wasm:prefer-inline")
int _jsStringLastIndexOf(
  WasmExternRef? string,
  WasmExternRef? pattern,
  int start,
) => js
    .JS<double>(
      '(s, p, i) => s.lastIndexOf(p, i)',
      string,
      pattern,
      start.toDouble(),
    )
    .toInt();

// TODO(joshualitt): Create a subtype of `JSArrayImpl` that can support lazily
// converting arguments `toDart` and return that here.
@pragma("wasm:prefer-inline")
List<String> _jsStringSplitToDart(
  WasmExternRef? string,
  WasmExternRef? token,
) => (js.JSValue(_jsStringSplit(string, token)) as JSArray).toDart
    .map((JSAny? a) => (a as JSString).toDart)
    .toList();

WasmExternRef? _jsStringSplit(WasmExternRef? string, WasmExternRef? token) =>
    js.JS<WasmExternRef?>(
      '(string, token) => string.split(token)',
      string,
      token,
    );

bool _jsIdentical(WasmExternRef? ref1, WasmExternRef? ref2) =>
    js.JS<bool>('Object.is', ref1, ref2);

@pragma("wasm:prefer-inline")
int jsCharCodeAt(WasmExternRef? stringRef, int index) =>
    _jsStringCharCodeAtImport(
      stringRef,
      WasmI32.fromInt(index),
    ).toIntUnsigned();

@pragma("wasm:prefer-inline")
WasmExternRef _jsSubstring(
  WasmExternRef? stringRef,
  int startIndex,
  int endIndex,
) => _jsStringSubstringImport(
  stringRef,
  WasmI32.fromInt(startIndex),
  WasmI32.fromInt(endIndex),
);

@pragma("wasm:prefer-inline")
int _jsLength(WasmExternRef? stringRef) =>
    _jsStringLengthImport(stringRef).toIntUnsigned();

@pragma("wasm:prefer-inline")
bool _jsEquals(WasmExternRef? s1, WasmExternRef? s2) =>
    _jsStringEqualsImport(s1, s2).toBool();

@pragma("wasm:prefer-inline")
int _jsCompare(WasmExternRef? s1, WasmExternRef? s2) =>
    _jsStringCompareImport(s1, s2).toIntSigned();

@pragma("wasm:import", "wasm:js-string.charCodeAt")
external WasmI32 _jsStringCharCodeAtImport(WasmExternRef? s, WasmI32 index);

@pragma("wasm:import", "wasm:js-string.compare")
external WasmI32 _jsStringCompareImport(WasmExternRef? s1, WasmExternRef? s2);

@pragma("wasm:import", "wasm:js-string.concat")
external WasmExternRef _jsStringConcatImport(
  WasmExternRef? s1,
  WasmExternRef? s2,
);

@pragma("wasm:import", "wasm:js-string.equals")
external WasmI32 _jsStringEqualsImport(WasmExternRef? s1, WasmExternRef? s2);

@pragma("wasm:import", "wasm:js-string.fromCharCode")
external WasmExternRef _jsStringFromCharCodeImport(WasmI32 c);

@pragma("wasm:import", "wasm:js-string.fromCodePoint")
external WasmExternRef _jsStringFromCodePointImport(WasmI32 c);

@pragma("wasm:import", "wasm:js-string.length")
external WasmI32 _jsStringLengthImport(WasmExternRef? s);

@pragma("wasm:import", "wasm:js-string.substring")
external WasmExternRef _jsStringSubstringImport(
  WasmExternRef? s,
  WasmI32 startIndex,
  WasmI32 endIndex,
);

@pragma("wasm:import", "wasm:js-string.fromCharCodeArray")
external WasmExternRef jsStringFromCharCodeArray(
  WasmArray<WasmI16>? array,
  WasmI32 start,
  WasmI32 end,
);

@pragma("wasm:import", "wasm:js-string.intoCharCodeArray")
external WasmI32 jsStringIntoCharCodeArray(
  WasmExternRef? s,
  WasmArray<WasmI16>? array,
  WasmI32 start,
);
