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

@ReifyFunctionTypes(false)
library dart._runtime;

import 'dart:async';
import 'dart:collection';

import 'dart:_debugger' show stackTraceMapper, trackCall;
import 'dart:_foreign_helper' show JS, JSExportName, rest, spread;
import 'dart:_interceptors' show JSArray, jsNull, JSFunction, NativeError;
import 'dart:_internal' as internal show Symbol;
import 'dart:_js_helper'
    show
        AssertionErrorImpl,
        BooleanConversionAssertionError,
        CastErrorImpl,
        DartIterator,
        TypeErrorImpl,
        JsLinkedHashMap,
        ImmutableMap,
        PrivateSymbol,
        ReifyFunctionTypes,
        NoReifyGeneric,
        notNull,
        undefined;

export 'dart:_debugger' show getDynamicStats, clearDynamicStats, trackCall;

part 'utils.dart';
part 'classes.dart';
part 'rtti.dart';
part 'types.dart';
part 'errors.dart';
part 'operations.dart';

// TODO(vsm): Move polyfill code to dart:html.
// Note, native extensions are registered onto types in dart.global.
// This polyfill needs to run before the corresponding dart:html code is run.
final _polyfilled = JS('', 'Symbol("_polyfilled")');

bool polyfill(window) => JS('', '''(() => {
  if ($window[$_polyfilled]) return false;
  $window[$_polyfilled] = true;

  if (typeof $window.NodeList !== "undefined") {
    // TODO(vsm): Do we still need these?
    $window.NodeList.prototype.get = function(i) { return this[i]; };
    $window.NamedNodeMap.prototype.get = function(i) { return this[i]; };
    $window.DOMTokenList.prototype.get = function(i) { return this[i]; };
    $window.HTMLCollection.prototype.get = function(i) { return this[i]; };

    // Expose constructors for DOM types dart:html needs to assume are
    // available on window.
    if (typeof $window.PannerNode == "undefined") {
      let audioContext;
      if (typeof $window.AudioContext == "undefined" &&
          (typeof $window.webkitAudioContext != "undefined")) {
        audioContext = new $window.webkitAudioContext();
      } else {
        audioContext = new $window.AudioContext();
        $window.StereoPannerNode =
            audioContext.createStereoPanner().constructor;
      }
      $window.PannerNode = audioContext.createPanner().constructor;
    }
    if (typeof $window.AudioSourceNode == "undefined") {
      $window.AudioSourceNode = MediaElementAudioSourceNode.__proto__;
    }
    if (typeof $window.FontFaceSet == "undefined") {
      // CSS Font Loading is not supported on Edge.
      if (typeof $window.document.fonts != "undefined") {
        $window.FontFaceSet = $window.document.fonts.__proto__.constructor;
      }
    }
    if (typeof $window.MemoryInfo == "undefined") {
      if (typeof $window.performance.memory != "undefined") {
        $window.MemoryInfo = $window.performance.memory.constructor;
      }
    }
    if (typeof $window.Geolocation == "undefined") {
      $window.Geolocation == $window.navigator.geolocation.constructor;
    }
    if (typeof $window.Animation == "undefined") {
      let d = $window.document.createElement('div');
      if (typeof d.animate != "undefined") {
        $window.Animation = d.animate(d).constructor;
      }
    }
    if (typeof $window.SourceBufferList == "undefined") {
      if ('MediaSource' in $window) {
        $window.SourceBufferList =
          new $window.MediaSource().sourceBuffers.constructor;
      }
    }
    if (typeof $window.SpeechRecognition == "undefined") {
      $window.SpeechRecognition = $window.webkitSpeechRecognition;
      $window.SpeechRecognitionError = $window.webkitSpeechRecognitionError;
      $window.SpeechRecognitionEvent = $window.webkitSpeechRecognitionEvent;
    }
  }
  return true;
})()''');

@JSExportName('global')
final global_ = JS('', '''
  function () {
    // Find global object.
    var globalState = (typeof window != "undefined") ? window
      : (typeof global != "undefined") ? global
      : (typeof self != "undefined") ? self : null;
    if (!globalState) {
      // Some platforms (e.g., d8) do not define any of the above.  The
      // following is a non-CSP safe way to access the global object:
      globalState = new Function('return this;')();
    }

    $polyfill(globalState);

    // By default, stack traces cutoff at 10.  Set the limit to Infinity for
    // better debugging.
    if (globalState.Error) {
      globalState.Error.stackTraceLimit = Infinity;
    }

    // These settings must be configured before the application starts so that
    // user code runs with the correct configuration.
    let settings = 'ddcSettings' in globalState ? globalState.ddcSettings : {};
    $trapRuntimeErrors(
        'trapRuntimeErrors' in settings ? settings.trapRuntimeErrors : false);

    $ignoreAllErrors(
        'ignoreAllErrors' in settings ? settings.ignoreAllErrors : false);

    $trackProfile(
        'trackProfile' in settings ? settings.trackProfile : false);

    return globalState;
  }()
''');

void trackProfile(bool flag) {
  JS('', 'dart.__trackProfile = #', flag);
}

final JsSymbol = JS('', 'Symbol');

/// The prototype used for all Dart libraries.
///
/// This makes it easy to identify Dart library objects, and also improves
/// performance (JS engines such as V8 tend to assume `Object.create(null)` is
/// used for a Map, so they don't optimize it as they normally would for
/// class-like objects).
///
/// The `dart.library` field is set by the compiler during SDK bootstrapping
/// (because it is needed for dart:_runtime itself), so we don't need to
/// initialize it here. The name `dart.library` is used because it reads nicely,
/// for example:
///
///     const my_library = Object.create(dart.library);
///
Object libraryPrototype = JS('', 'dart.library');

// TODO(vsm): Remove once this flag we've removed the ability to
// whitelist / fallback on the old behavior.
bool startAsyncSynchronously = true;
void setStartAsyncSynchronously([bool value = true]) {
  startAsyncSynchronously = value;
}

/// A list of all JS Maps used for caching results, such as by [isSubtypeOf] and
/// [generic].
///
/// This is used by [hotRestart] to ensure we don't leak types from previous
/// libraries.
@notNull
final List<Object> _cacheMaps = JS('!', '[]');

/// A list of functions to reset static fields back to their uninitialized
/// state.
///
/// This is populated by [defineLazyField], and only contains the list of fields
/// that have actually been initialized.
@notNull
final List<void Function()> _resetFields = JS('', '[]');

/// Clears out runtime state in `dartdevc` so we can hot-restart.
///
/// This should be called when the user requests a hot-restart, when the UI is
/// handling that user action.
void hotRestart() {
  // TODO(jmesserly): we need to prevent all pending callbacks from firing.
  for (var f in _resetFields) f();
  _resetFields.clear();
  for (var m in _cacheMaps) JS('', '#.clear()', m);
  _cacheMaps.clear();
  JS('', '#.clear()', constantMaps);
}

/// Marks enqueuing an async operation.
///
/// This will be called by library code when enqueuing an async operation
/// controlled by the JavaScript event handler.
///
/// It will also call [removeAsyncCallback] when Dart callback is about to be
/// executed (note this is called *before* the callback executes, so more
/// async operations could be added from that).
void Function() addAsyncCallback = JS('', 'function() {}');

/// Marks leaving a javascript async operation.
///
/// See [addAsyncCallback].
void Function() removeAsyncCallback = JS('', 'function() {}');
