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

library dart._js_helper;

import 'dart:async' show Zone;
import 'dart:collection';

import 'dart:_foreign_helper' show JS, JSExportName;

import 'dart:_interceptors';
import 'dart:_internal'
    show
        EfficientLengthIterable,
        MappedIterable,
        IterableElementError,
        SubListIterable;

import 'dart:_native_typed_data';
import 'dart:_runtime' as dart;

part 'annotations.dart';
part 'linked_hash_map.dart';
part 'identity_hash_map.dart';
part 'custom_hash_map.dart';
part 'native_helper.dart';
part 'regexp_helper.dart';
part 'string_helper.dart';
part 'js_rti.dart';

class _Patch {
  const _Patch();
}

const _Patch patch = _Patch();

/// Adapts a JS `[Symbol.iterator]` to a Dart `get iterator`.
///
/// This is the inverse of `JsIterator`, for classes where we can more
/// efficiently obtain a JS iterator instead of a Dart one.
///
// TODO(jmesserly): this adapter is to work around
// https://github.com/dart-lang/sdk/issues/28320
class DartIterator<E> implements Iterator<E> {
  final _jsIterator;
  E? _current;

  DartIterator(this._jsIterator);

  E get current => _current as E;

  bool moveNext() {
    final ret = JS('', '#.next()', _jsIterator);
    _current = JS('', '#.value', ret);
    return JS<bool>('!', '!#.done', ret);
  }
}

/// Used to compile `sync*`.
class SyncIterable<E> extends IterableBase<E> {
  final Function() _initGenerator;
  SyncIterable(this._initGenerator);

  @JSExportName('Symbol.iterator')
  _jsIterator() => _initGenerator();

  get iterator => DartIterator(_initGenerator());
}

class Primitives {
  static int? parseInt(@nullCheck String source, int? _radix) {
    var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
    // This isn't reified List<String?>?, but it's safe to use as long as we use
    // it locally and don't expose it to user code.
    var match = JS<List<String?>?>('', '#.exec(#)', re, source);
    int digitsIndex = 1;
    int hexIndex = 2;
    int decimalIndex = 3;
    if (match == null) {
      // TODO(sra): It might be that the match failed due to unrecognized U+0085
      // spaces.  We could replace them with U+0020 spaces and try matching
      // again.
      return null;
    }
    var decimalMatch = match[decimalIndex];
    if (_radix == null) {
      if (decimalMatch != null) {
        // Cannot fail because we know that the digits are all decimal.
        return JS<int>('!', r'parseInt(#, 10)', source);
      }
      if (match[hexIndex] != null) {
        // Cannot fail because we know that the digits are all hex.
        return JS<int>('!', r'parseInt(#, 16)', source);
      }
      return null;
    }
    @notNull
    var radix = _radix;
    if (radix < 2 || radix > 36) {
      throw RangeError.range(radix, 2, 36, 'radix');
    }
    if (radix == 10 && decimalMatch != null) {
      // Cannot fail because we know that the digits are all decimal.
      return JS<int>('!', r'parseInt(#, 10)', source);
    }
    // If radix >= 10 and we have only decimal digits the string is safe.
    // Otherwise we need to check the digits.
    if (radix < 10 || decimalMatch == null) {
      // We know that the characters must be ASCII as otherwise the
      // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
      // guaranteed to be a safe operation, since it preserves digits
      // and lower-cases ASCII letters.
      int maxCharCode;
      if (radix <= 10) {
        // Allow all digits less than the radix. For example 0, 1, 2 for
        // radix 3.
        // "0".codeUnitAt(0) + radix - 1;
        maxCharCode = (0x30 - 1) + radix;
      } else {
        // Letters are located after the digits in ASCII. Therefore we
        // only check for the character code. The regexp above made already
        // sure that the string does not contain anything but digits or
        // letters.
        // "a".codeUnitAt(0) + (radix - 10) - 1;
        maxCharCode = (0x61 - 10 - 1) + radix;
      }
      assert(match[digitsIndex] is String);
      String digitsPart = JS<String>('!', '#[#]', match, digitsIndex);
      for (int i = 0; i < digitsPart.length; i++) {
        int characterCode = digitsPart.codeUnitAt(i) | 0x20;
        if (characterCode > maxCharCode) {
          return null;
        }
      }
    }
    // The above matching and checks ensures the source has at least one digits
    // and all digits are suitable for the radix, so parseInt cannot return NaN.
    return JS<int>('!', r'parseInt(#, #)', source, radix);
  }

  static double? parseDouble(@nullCheck String source) {
    // Notice that JS parseFloat accepts garbage at the end of the string.
    // Accept only:
    // - [+/-]NaN
    // - [+/-]Infinity
    // - a Dart double literal
    // We do allow leading or trailing whitespace.
    if (!JS(
        'bool',
        r'/^\s*[+-]?(?:Infinity|NaN|'
            r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
        source)) {
      return null;
    }
    var result = JS<double>('!', r'parseFloat(#)', source);
    if (result.isNaN) {
      var trimmed = source.trim();
      if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
        return result;
      }
      return null;
    }
    return result;
  }

  /** `r"$".codeUnitAt(0)` */
  static const int DOLLAR_CHAR_VALUE = 36;

  static int dateNow() => JS<int>('!', r'Date.now()');

  static void initTicker() {
    if (timerFrequency != 0) return;
    // Start with low-resolution. We overwrite the fields if we find better.
    timerFrequency = 1000;
    if (JS<bool>('!', 'typeof window == "undefined"')) return;
    var jsWindow = JS('var', 'window');
    if (jsWindow == null) return;
    var performance = JS('var', '#.performance', jsWindow);
    if (performance == null) return;
    if (JS<bool>('!', 'typeof #.now != "function"', performance)) return;
    timerFrequency = 1000000;
    timerTicks = () => (1000 * JS<num>('!', '#.now()', performance)).floor();
  }

  /// 0 frequency indicates the default uninitialized state.
  static int timerFrequency = 0;
  static int Function() timerTicks = dateNow; // Low-resolution version.

  static bool get isD8 {
    return JS(
        'bool',
        'typeof version == "function"'
            ' && typeof os == "object" && "system" in os');
  }

  static bool get isJsshell {
    return JS(
        'bool', 'typeof version == "function" && typeof system == "function"');
  }

  static String currentUri() {
    // In a browser return self.location.href.
    if (JS<bool>('!', '!!#.location', dart.global_)) {
      return JS<String>('!', '#.location.href', dart.global_);
    }

    // TODO(vsm): Consider supporting properly in non-browser settings.
    return '';
  }

  // This is to avoid stack overflows due to very large argument arrays in
  // apply().  It fixes http://dartbug.com/6919
  @notNull
  static String _fromCharCodeApply(List<int> array) {
    const kMaxApply = 500;
    @nullCheck
    int end = array.length;
    if (end <= kMaxApply) {
      return JS<String>('!', r'String.fromCharCode.apply(null, #)', array);
    }
    String result = '';
    for (int i = 0; i < end; i += kMaxApply) {
      int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end;
      result = JS(
          'String',
          r'# + String.fromCharCode.apply(null, #.slice(#, #))',
          result,
          array,
          i,
          chunkEnd);
    }
    return result;
  }

  @notNull
  static String stringFromCodePoints(JSArray<int> codePoints) {
    List<int> a = <int>[];
    for (@nullCheck var i in codePoints) {
      if (i <= 0xffff) {
        a.add(i);
      } else if (i <= 0x10ffff) {
        a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff)));
        a.add(0xdc00 + (i & 0x3ff));
      } else {
        throw argumentErrorValue(i);
      }
    }
    return _fromCharCodeApply(a);
  }

  @notNull
  static String stringFromCharCodes(JSArray<int> charCodes) {
    for (@nullCheck var i in charCodes) {
      if (i < 0) throw argumentErrorValue(i);
      if (i > 0xffff) return stringFromCodePoints(charCodes);
    }
    return _fromCharCodeApply(charCodes);
  }

  // [start] and [end] are validated.
  @notNull
  static String stringFromNativeUint8List(
      NativeUint8List charCodes, @nullCheck int start, @nullCheck int end) {
    const kMaxApply = 500;
    if (end <= kMaxApply && start == 0 && end == charCodes.length) {
      return JS<String>('!', r'String.fromCharCode.apply(null, #)', charCodes);
    }
    String result = '';
    for (int i = start; i < end; i += kMaxApply) {
      int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end;
      result = JS(
          'String',
          r'# + String.fromCharCode.apply(null, #.subarray(#, #))',
          result,
          charCodes,
          i,
          chunkEnd);
    }
    return result;
  }

  @notNull
  static String stringFromCharCode(@nullCheck int charCode) {
    if (0 <= charCode) {
      if (charCode <= 0xffff) {
        return JS<String>('!', 'String.fromCharCode(#)', charCode);
      }
      if (charCode <= 0x10ffff) {
        var bits = charCode - 0x10000;
        var low = 0xDC00 | (bits & 0x3ff);
        var high = 0xD800 | (bits >> 10);
        return JS<String>('!', 'String.fromCharCode(#, #)', high, low);
      }
    }
    throw RangeError.range(charCode, 0, 0x10ffff);
  }

  static String flattenString(String str) {
    return JS<String>('!', "#.charCodeAt(0) == 0 ? # : #", str, str, str);
  }

  static String getTimeZoneName(DateTime receiver) {
    // Firefox and Chrome emit the timezone in parenthesis.
    // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)".
    // We extract this name using a regexp.
    var d = lazyAsJsDate(receiver);
    // In this method all calls to `exec()` include a single capture group and
    // it is only read if there is a match so a value will be present. To avoid
    // extra null checks or casts from dynamic we type the return type of
    // `exec()` to always contain non-nullable Strings.
    var match = JS<List<String>?>('', r'/\((.*)\)/.exec(#.toString())', d);
    if (match != null) return match[1];

    // Internet Explorer 10+ emits the zone name without parenthesis:
    // Example: Thu Oct 31 14:07:44 PDT 2013
    match = JS<List<String>?>(
        '',
        // Thu followed by a space.
        r'/^[A-Z,a-z]{3}\s'
            // Oct 31 followed by space.
            r'[A-Z,a-z]{3}\s\d+\s'
            // Time followed by a space.
            r'\d{2}:\d{2}:\d{2}\s'
            // The time zone name followed by a space.
            r'([A-Z]{3,5})\s'
            // The year.
            r'\d{4}$/'
            '.exec(#.toString())',
        d);
    if (match != null) return match[1];

    // IE 9 and Opera don't provide the zone name. We fall back to emitting the
    // UTC/GMT offset.
    // Example (IE9): Wed Nov 20 09:51:00 UTC+0100 2013
    //       (Opera): Wed Nov 20 2013 11:03:38 GMT+0100
    match =
        JS<List<String>?>('', r'/(?:GMT|UTC)[+-]\d{4}/.exec(#.toString())', d);
    if (match != null) return match[0];
    return "";
  }

  static int getTimeZoneOffsetInMinutes(DateTime receiver) {
    // Note that JS and Dart disagree on the sign of the offset.
    return -JS<int>('!', r'#.getTimezoneOffset()', lazyAsJsDate(receiver));
  }

  static int? valueFromDecomposedDate(
      @nullCheck int years,
      @nullCheck int month,
      @nullCheck int day,
      @nullCheck int hours,
      @nullCheck int minutes,
      @nullCheck int seconds,
      @nullCheck int milliseconds,
      @nullCheck bool isUtc) {
    final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
    var jsMonth = month - 1;
    // The JavaScript Date constructor 'corrects' year NN to 19NN. Sidestep that
    // correction by adjusting years out of that range and compensating with an
    // adjustment of months. This hack should not be sensitive to leap years but
    // use 400 just in case.
    if (0 <= years && years < 100) {
      years += 400;
      jsMonth -= 400 * 12;
    }
    int value;
    if (isUtc) {
      value = JS<int>('!', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth,
          day, hours, minutes, seconds, milliseconds);
    } else {
      value = JS<int>('!', r'new Date(#, #, #, #, #, #, #).valueOf()', years,
          jsMonth, day, hours, minutes, seconds, milliseconds);
    }
    if (value.isNaN ||
        value < -MAX_MILLISECONDS_SINCE_EPOCH ||
        value > MAX_MILLISECONDS_SINCE_EPOCH) {
      return null;
    }
    if (years <= 0 || years < 100) return patchUpY2K(value, years, isUtc);
    return value;
  }

  static int patchUpY2K(value, years, isUtc) {
    var date = JS<int>('!', r'new Date(#)', value);
    if (isUtc) {
      JS<int>('!', r'#.setUTCFullYear(#)', date, years);
    } else {
      JS<int>('!', r'#.setFullYear(#)', date, years);
    }
    return JS<int>('!', r'#.valueOf()', date);
  }

  // Lazily keep a JS Date stored in the JS object.
  static lazyAsJsDate(DateTime receiver) {
    if (JS<bool>('!', r'#.date === (void 0)', receiver)) {
      JS('void', r'#.date = new Date(#)', receiver,
          receiver.millisecondsSinceEpoch);
    }
    return JS('var', r'#.date', receiver);
  }

  // The getters for date and time parts below add a positive integer to ensure
  // that the result is really an integer, because the JavaScript implementation
  // may return -0.0 instead of 0.

  static int getYear(DateTime receiver) {
    return (receiver.isUtc)
        ? JS<int>('!', r'(#.getUTCFullYear() + 0)', lazyAsJsDate(receiver))
        : JS<int>('!', r'(#.getFullYear() + 0)', lazyAsJsDate(receiver));
  }

  static int getMonth(DateTime receiver) {
    return (receiver.isUtc)
        ? JS<int>('!', r'#.getUTCMonth() + 1', lazyAsJsDate(receiver))
        : JS<int>('!', r'#.getMonth() + 1', lazyAsJsDate(receiver));
  }

  static int getDay(DateTime receiver) {
    return (receiver.isUtc)
        ? JS<int>('!', r'(#.getUTCDate() + 0)', lazyAsJsDate(receiver))
        : JS<int>('!', r'(#.getDate() + 0)', lazyAsJsDate(receiver));
  }

  static int getHours(DateTime receiver) {
    return (receiver.isUtc)
        ? JS<int>('!', r'(#.getUTCHours() + 0)', lazyAsJsDate(receiver))
        : JS<int>('!', r'(#.getHours() + 0)', lazyAsJsDate(receiver));
  }

  static int getMinutes(DateTime receiver) {
    return (receiver.isUtc)
        ? JS<int>('!', r'(#.getUTCMinutes() + 0)', lazyAsJsDate(receiver))
        : JS<int>('!', r'(#.getMinutes() + 0)', lazyAsJsDate(receiver));
  }

  static int getSeconds(DateTime receiver) {
    return (receiver.isUtc)
        ? JS<int>('!', r'(#.getUTCSeconds() + 0)', lazyAsJsDate(receiver))
        : JS<int>('!', r'(#.getSeconds() + 0)', lazyAsJsDate(receiver));
  }

  static int getMilliseconds(DateTime receiver) {
    return (receiver.isUtc)
        ? JS<int>('!', r'(#.getUTCMilliseconds() + 0)', lazyAsJsDate(receiver))
        : JS<int>('!', r'(#.getMilliseconds() + 0)', lazyAsJsDate(receiver));
  }

  static int getWeekday(DateTime receiver) {
    int weekday = (receiver.isUtc)
        ? JS<int>('!', r'#.getUTCDay() + 0', lazyAsJsDate(receiver))
        : JS<int>('!', r'#.getDay() + 0', lazyAsJsDate(receiver));
    // Adjust by one because JS weeks start on Sunday.
    return (weekday + 6) % 7 + 1;
  }

  static num valueFromDateString(str) {
    if (str is! String) throw argumentErrorValue(str);
    num value = JS('!', r'Date.parse(#)', str);
    if (value.isNaN) throw argumentErrorValue(str);
    return value;
  }

  static Object? getProperty(Object? object, Object key) {
    if (object == null || object is bool || object is num || object is String) {
      throw argumentErrorValue(object);
    }
    return JS('var', '#[#]', object, key);
  }

  static void setProperty(object, key, value) {
    if (object == null || object is bool || object is num || object is String) {
      throw argumentErrorValue(object);
    }
    JS('void', '#[#] = #', object, key, value);
  }
}

/**
 * Diagnoses an indexing error. Returns the ArgumentError or RangeError that
 * describes the problem.
 */
Error diagnoseIndexError(indexable, int index) {
  int length = indexable.length;
  // The following returns the same error that would be thrown by calling
  // [RangeError.checkValidIndex] with no optional parameters provided.
  if (index < 0 || index >= length) {
    return RangeError.index(index, indexable, 'index', null, length);
  }
  // The above should always match, but if it does not, use the following.
  return RangeError.value(index, 'index');
}

/**
 * Diagnoses a range error. Returns the ArgumentError or RangeError that
 * describes the problem.
 */
Error diagnoseRangeError(int? start, int? end, int length) {
  if (start == null) {
    return ArgumentError.value(start, 'start');
  }
  if (start < 0 || start > length) {
    return RangeError.range(start, 0, length, 'start');
  }
  if (end != null) {
    if (end < start || end > length) {
      return RangeError.range(end, start, length, 'end');
    }
  }
  // The above should always match, but if it does not, use the following.
  return ArgumentError.value(end, "end");
}

@notNull
int stringLastIndexOfUnchecked(receiver, element, start) =>
    JS<int>('!', r'#.lastIndexOf(#, #)', receiver, element, start);

/// 'factory' for constructing ArgumentError.value to keep the call sites small.
ArgumentError argumentErrorValue(object) {
  return ArgumentError.value(object);
}

void throwArgumentErrorValue(value) {
  throw argumentErrorValue(value);
}

checkInt(value) {
  if (value is! int) throw argumentErrorValue(value);
  return value;
}

throwRuntimeError(message) {
  throw RuntimeError(message);
}

throwAbstractClassInstantiationError(className) {
  throw AbstractClassInstantiationError(className);
}

throwConcurrentModificationError(collection) {
  throw ConcurrentModificationError(collection);
}

class JsNoSuchMethodError extends Error implements NoSuchMethodError {
  final String? _message;
  final String? _method;
  final String? _receiver;

  JsNoSuchMethodError(this._message, match)
      : _method = match == null ? null : JS('String|Null', '#.method', match),
        _receiver =
            match == null ? null : JS('String|Null', '#.receiver', match);

  String toString() {
    if (_method == null) return 'NoSuchMethodError: $_message';
    if (_receiver == null) {
      return "NoSuchMethodError: method not found: '$_method' ($_message)";
    }
    return "NoSuchMethodError: "
        "method not found: '$_method' on '$_receiver' ($_message)";
  }
}

class UnknownJsTypeError extends Error {
  final String _message;

  UnknownJsTypeError(this._message);

  String toString() => _message.isEmpty ? 'Error' : 'Error: $_message';
}

/**
 * Called by generated code to build a map literal. [keyValuePairs] is
 * a list of key, value, key, value, ..., etc.
 */
fillLiteralMap(keyValuePairs, Map result) {
  // TODO(johnniwinther): Use JSArray to optimize this code instead of calling
  // [getLength] and [getIndex].
  int index = 0;
  int length = getLength(keyValuePairs);
  while (index < length) {
    var key = getIndex(keyValuePairs, index++);
    var value = getIndex(keyValuePairs, index++);
    result[key] = value;
  }
  return result;
}

bool jsHasOwnProperty(jsObject, String property) {
  return JS<bool>('!', r'#.hasOwnProperty(#)', jsObject, property);
}

jsPropertyAccess(jsObject, String property) {
  return JS('var', r'#[#]', jsObject, property);
}

/**
 * Called at the end of unaborted switch cases to get the singleton
 * FallThroughError exception that will be thrown.
 */
getFallThroughError() => FallThroughErrorImplementation();

/**
 * A metadata annotation describing the types instantiated by a native element.
 *
 * The annotation is valid on a native method and a field of a native class.
 *
 * By default, a field of a native class is seen as an instantiation point for
 * all native classes that are a subtype of the field's type, and a native
 * method is seen as an instantiation point fo all native classes that are a
 * subtype of the method's return type, or the argument types of the declared
 * type of the method's callback parameter.
 *
 * An @[Creates] annotation overrides the default set of instantiated types.  If
 * one or more @[Creates] annotations are present, the type of the native
 * element is ignored, and the union of @[Creates] annotations is used instead.
 * The names in the strings are resolved and the program will fail to compile
 * with dart2js if they do not name types.
 *
 * The argument to [Creates] is a string.  The string is parsed as the names of
 * one or more types, separated by vertical bars `|`.  There are some special
 * names:
 *
 * * `=Object`. This means 'exactly Object', which is a plain JavaScript object
 *   with properties and none of the subtypes of Object.
 *
 * Example: we may know that a method always returns a specific implementation:
 *
 *     @Creates('_NodeList')
 *     List<Node> getElementsByTagName(String tag) native;
 *
 * Useful trick: A method can be marked as not instantiating any native classes
 * with the annotation `@Creates('Null')`.  This is useful for fields on native
 * classes that are used only in Dart code.
 *
 *     @Creates('Null')
 *     var _cachedFoo;
 */
class Creates {
  final String types;
  const Creates(this.types);
}

/**
 * A metadata annotation describing the types returned or yielded by a native
 * element.
 *
 * The annotation is valid on a native method and a field of a native class.
 *
 * By default, a native method or field is seen as returning or yielding all
 * subtypes if the method return type or field type.  This annotation allows a
 * more precise set of types to be specified.
 *
 * See [Creates] for the syntax of the argument.
 *
 * Example: IndexedDB keys are numbers, strings and JavaScript Arrays of keys.
 *
 *     @Returns('String|num|JSExtendableArray')
 *     dynamic key;
 *
 *     // Equivalent:
 *     @Returns('String') @Returns('num') @Returns('JSExtendableArray')
 *     dynamic key;
 */
class Returns {
  final String types;
  const Returns(this.types);
}

/**
 * A metadata annotation placed on native methods and fields of native classes
 * to specify the JavaScript name.
 *
 * This example declares a Dart field + getter + setter called `$dom_title` that
 * corresponds to the JavaScript property `title`.
 *
 *     class Document native "*Foo" {
 *       @JSName('title')
 *       String $dom_title;
 *     }
 */
class JSName {
  final String name;
  const JSName(this.name);
}

/**
 * Special interface recognized by the compiler and implemented by DOM
 * objects that support integer indexing. This interface is not
 * visible to anyone, and is only injected into special libraries.
 */
abstract class JavaScriptIndexingBehavior<E> extends JSMutableIndexable<E> {}

/// Thrown by type assertions that fail.
class TypeErrorImpl extends Error implements TypeError, CastError {
  final String _message;

  TypeErrorImpl(this._message);

  String toString() => _message;
}

class FallThroughErrorImplementation extends FallThroughError {
  String toString() => "Switch case fall-through.";
}

/**
 * Error thrown when a runtime error occurs.
 */
class RuntimeError extends Error {
  final message;
  RuntimeError(this.message);
  String toString() => "RuntimeError: $message";
}

class DeferredNotLoadedError extends Error implements NoSuchMethodError {
  String enclosingLibrary;
  String importPrefix;

  DeferredNotLoadedError(this.enclosingLibrary, this.importPrefix);

  String toString() {
    return 'Deferred import $importPrefix (from $enclosingLibrary) was not loaded.';
  }
}

/// Error thrown by DDC when an `assert()` fails (with or without a message).
class AssertionErrorImpl extends AssertionError {
  final String? _fileUri;
  final int? _line;
  final int? _column;
  final String? _conditionSource;

  AssertionErrorImpl(Object? message,
      [this._fileUri, this._line, this._column, this._conditionSource])
      : super(message);

  String toString() {
    var failureMessage = "";
    if (_fileUri != null &&
        _line != null &&
        _column != null &&
        _conditionSource != null) {
      failureMessage += "$_fileUri:${_line}:${_column}\n$_conditionSource\n";
    }
    failureMessage +=
        message != null ? Error.safeToString(message) : "is not true";

    return "Assertion failed: $failureMessage";
  }
}

/**
 * Creates a random number with 64 bits of randomness.
 *
 * This will be truncated to the 53 bits available in a double.
 */
int random64() {
  // TODO(lrn): Use a secure random source.
  int int32a = JS("int", "(Math.random() * 0x100000000) >>> 0");
  int int32b = JS("int", "(Math.random() * 0x100000000) >>> 0");
  return int32a + int32b * 0x100000000;
}

class BooleanConversionAssertionError extends AssertionError {
  toString() => 'Failed assertion: boolean expression must not be null';
}

// Hook to register new global object.  This is invoked from dart:html
// whenever a new window is accessed for the first time.
void registerGlobalObject(object) {
  try {
    if (dart.polyfill(object)) {
      dart.applyAllExtensions(object);
    }
  } catch (e) {
    // This may fail due to cross-origin errors.  In that case, we shouldn't
    // need to polyfill as we can't get objects from that frame.

    // TODO(vsm): Detect this more robustly - ideally before we try to polyfill.
  }
}

/// Expose browser JS classes.
void applyExtension(name, nativeObject) {
  dart.applyExtension(name, nativeObject);
}

/// Hook to apply extensions on native JS classes defined in a native unit test.
void applyTestExtensions(List<String> names) {
  names.forEach(dart.applyExtensionForTesting);
}

/// Used internally by DDC to map ES6 symbols to Dart.
class PrivateSymbol implements Symbol {
  // TODO(jmesserly): could also get this off the native symbol instead of
  // storing it. Mirrors already does this conversion.
  final String _name;
  final Object _nativeSymbol;

  const PrivateSymbol(this._name, this._nativeSymbol);

  static String getName(Symbol symbol) => (symbol as PrivateSymbol)._name;

  static Object? getNativeSymbol(Symbol symbol) {
    if (symbol is PrivateSymbol) return symbol._nativeSymbol;
    return null;
  }

  bool operator ==(other) =>
      other is PrivateSymbol &&
      _name == other._name &&
      identical(_nativeSymbol, other._nativeSymbol);

  get hashCode => _name.hashCode;

  // TODO(jmesserly): is this equivalent to _nativeSymbol toString?
  toString() => 'Symbol("$_name")';
}

/// Asserts that if [value] is a function, it is a JavaScript function or has
/// been wrapped by [allowInterop].
///
/// This function does not recurse if [value] is a collection.
void assertInterop(Object? value) {
  if (value is Function) dart.assertInterop(value);
}

/// Like [assertInterop], except iterates over a list of arguments
/// non-recursively.
void assertInteropArgs(List<Object?> args) => args.forEach(assertInterop);

/// Wraps the given [callback] within the current Zone.
void Function(T)? wrapZoneUnaryCallback<T>(void Function(T)? callback) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.root) return callback;
  if (callback == null) return null;
  return Zone.current.bindUnaryCallbackGuarded(callback);
}
