// 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.

/**
 * Support for interoperating with JavaScript.
 *
 * This library provides access to JavaScript objects from Dart, allowing
 * Dart code to get and set properties, and call methods of JavaScript objects
 * and invoke JavaScript functions. The library takes care of converting
 * between Dart and JavaScript objects where possible, or providing proxies if
 * conversion isn't possible.
 *
 * This library does not yet make Dart objects usable from JavaScript, their
 * methods and proeprties are not accessible, though it does allow Dart
 * functions to be passed into and called from JavaScript.
 *
 * [JsObject] is the core type and represents a proxy of a JavaScript object.
 * JsObject gives access to the underlying JavaScript objects properties and
 * methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
 * created from proxies to JavaScript constructors.
 *
 * The top-level getter [context] provides a [JsObject] that represents the
 * global object in JavaScript, usually `window`.
 *
 * The following example shows an alert dialog via a JavaScript call to the
 * global function `alert()`:
 *
 *     import 'dart:js';
 *
 *     main() => context.callMethod('alert', ['Hello from Dart!']);
 *
 * This example shows how to create a [JsObject] from a JavaScript constructor
 * and access its properties:
 *
 *     import 'dart:js';
 *
 *     main() {
 *       var object = new JsObject(context['Object']);
 *       object['greeting'] = 'Hello';
 *       object['greet'] = (name) => "${object['greeting']} $name";
 *       var message = object.callMethod('greet', ['JavaScript']);
 *       context['console'].callMethod('log', [message]);
 *     }
 *
 * ## Proxying and automatic conversion
 *
 * When setting properties on a JsObject or passing arguments to a Javascript
 * method or function, Dart objects are automatically converted or proxied to
 * JavaScript objects. When accessing JavaScript properties, or when a Dart
 * closure is invoked from JavaScript, the JavaScript objects are also
 * converted to Dart.
 *
 * Functions and closures are proxied in such a way that they are callable. A
 * Dart closure assigned to a JavaScript property is proxied by a function in
 * JavaScript. A JavaScript function accessed from Dart is proxied by a
 * [JsFunction], which has a [apply] method to invoke it.
 *
 * The following types are transferred directly and not proxied:
 *
 * * "Basic" types: `null`, `bool`, `num`, `String`, `DateTime`
 * * `Blob`
 * * `Event`
 * * `HtmlCollection`
 * * `ImageData`
 * * `KeyRange`
 * * `Node`
 * * `NodeList`
 * * `TypedData`, including its subclasses like `Int32List`, but _not_
 *   `ByteBuffer`
 * * `Window`
 *
 * ## Converting collections with JsObject.jsify()
 *
 * To create a JavaScript collection from a Dart collection use the
 * [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
 * into JavaScript Objects and Arrays.
 *
 * The following expression creats a new JavaScript object with the properties
 * `a` and `b` defined:
 *
 *     var jsMap = new JsObject.jsify({'a': 1, 'b': 2});
 *
 * This expression creates a JavaScript array:
 *
 *     var jsArray = new JsObject.jsify([1, 2, 3]);
 */
library dart.js;

import 'dart:collection' show ListMixin;
import 'dart:nativewrappers';
import 'dart:math' as math;
import 'dart:mirrors' as mirrors;
import 'dart:html' as html;
import 'dart:_blink' as _blink;
import 'dart:html_common' as html_common;
import 'dart:indexed_db' as indexed_db;
import 'dart:typed_data';
import 'dart:core';

import 'cached_patches.dart';

// Pretend we are always in checked mode as we aren't interested in users
// running Dartium code outside of checked mode.
@Deprecated("Internal Use Only")
final bool CHECK_JS_INVOCATIONS = true;

final String _DART_RESERVED_NAME_PREFIX = r'JS$';
// If a private class is defined to use @JS we need to inject a non-private
// class with a name that will not cause collisions in the library so we can
// make JSObject implement that interface even though it is in a different
// library.
final String escapePrivateClassPrefix = r'$JSImplClass23402893498';

String _stripReservedNamePrefix(String name) =>
    name.startsWith(_DART_RESERVED_NAME_PREFIX)
        ? name.substring(_DART_RESERVED_NAME_PREFIX.length)
        : name;

_buildArgs(Invocation invocation) {
  if (invocation.namedArguments.isEmpty) {
    return invocation.positionalArguments;
  } else {
    var varArgs = new Map<String, Object>();
    invocation.namedArguments.forEach((symbol, val) {
      varArgs[mirrors.MirrorSystem.getName(symbol)] = val;
    });
    return invocation.positionalArguments.toList()
      ..add(JsNative.jsify(varArgs));
  }
}

final _allowedMethods = new Map<Symbol, _DeclarationSet>();
final _allowedGetters = new Map<Symbol, _DeclarationSet>();
final _allowedSetters = new Map<Symbol, _DeclarationSet>();

final _jsInterfaceTypes = new Set<mirrors.ClassMirror>();
@Deprecated("Internal Use Only")
Iterable<mirrors.ClassMirror> get jsInterfaceTypes => _jsInterfaceTypes;

class _StringLiteralEscape {
  // Character code constants.
  static const int BACKSPACE = 0x08;
  static const int TAB = 0x09;
  static const int NEWLINE = 0x0a;
  static const int CARRIAGE_RETURN = 0x0d;
  static const int FORM_FEED = 0x0c;
  static const int QUOTE = 0x22;
  static const int CHAR_$ = 0x24;
  static const int CHAR_0 = 0x30;
  static const int BACKSLASH = 0x5c;
  static const int CHAR_b = 0x62;
  static const int CHAR_f = 0x66;
  static const int CHAR_n = 0x6e;
  static const int CHAR_r = 0x72;
  static const int CHAR_t = 0x74;
  static const int CHAR_u = 0x75;

  final StringSink _sink;

  _StringLiteralEscape(this._sink);

  void writeString(String string) {
    _sink.write(string);
  }

  void writeStringSlice(String string, int start, int end) {
    _sink.write(string.substring(start, end));
  }

  void writeCharCode(int charCode) {
    _sink.writeCharCode(charCode);
  }

  /// ('0' + x) or ('a' + x - 10)
  static int hexDigit(int x) => x < 10 ? 48 + x : 87 + x;

  /// Write, and suitably escape, a string's content as a JSON string literal.
  void writeStringContent(String s) {
    // Identical to JSON string literal escaping except that we also escape $.
    int offset = 0;
    final int length = s.length;
    for (int i = 0; i < length; i++) {
      int charCode = s.codeUnitAt(i);
      if (charCode > BACKSLASH) continue;
      if (charCode < 32) {
        if (i > offset) writeStringSlice(s, offset, i);
        offset = i + 1;
        writeCharCode(BACKSLASH);
        switch (charCode) {
          case BACKSPACE:
            writeCharCode(CHAR_b);
            break;
          case TAB:
            writeCharCode(CHAR_t);
            break;
          case NEWLINE:
            writeCharCode(CHAR_n);
            break;
          case FORM_FEED:
            writeCharCode(CHAR_f);
            break;
          case CARRIAGE_RETURN:
            writeCharCode(CHAR_r);
            break;
          default:
            writeCharCode(CHAR_u);
            writeCharCode(CHAR_0);
            writeCharCode(CHAR_0);
            writeCharCode(hexDigit((charCode >> 4) & 0xf));
            writeCharCode(hexDigit(charCode & 0xf));
            break;
        }
      } else if (charCode == QUOTE ||
          charCode == BACKSLASH ||
          charCode == CHAR_$) {
        if (i > offset) writeStringSlice(s, offset, i);
        offset = i + 1;
        writeCharCode(BACKSLASH);
        writeCharCode(charCode);
      }
    }
    if (offset == 0) {
      writeString(s);
    } else if (offset < length) {
      writeStringSlice(s, offset, length);
    }
  }

  /**
   * Serialize a [num], [String], [bool], [Null], [List] or [Map] value.
   *
   * Returns true if the value is one of these types, and false if not.
   * If a value is both a [List] and a [Map], it's serialized as a [List].
   */
  bool writeStringLiteral(String str) {
    writeString('"');
    writeStringContent(str);
    writeString('"');
  }
}

String _escapeString(String str) {
  StringBuffer output = new StringBuffer();
  new _StringLiteralEscape(output)..writeStringLiteral(str);
  return output.toString();
}

/// A collection of methods where all methods have the same name.
/// This class is intended to optimize whether a specific invocation is
/// appropritate for at least some of the methods in the collection.
class _DeclarationSet {
  _DeclarationSet() : _members = <mirrors.DeclarationMirror>[];

  static bool _checkType(obj, mirrors.TypeMirror type) {
    if (obj == null) return true;
    return mirrors.reflectType(obj.runtimeType).isSubtypeOf(type);
  }

  /// Returns whether the return [value] has a type is consistent with the
  /// return type from at least one of the members matching the DeclarationSet.
  bool _checkReturnType(value) {
    if (value == null) return true;
    var valueMirror = mirrors.reflectType(value.runtimeType);
    for (var member in _members) {
      if (member is mirrors.VariableMirror || member.isGetter) {
        // TODO(jacobr): actually check return types for getters that return
        // function types.
        return true;
      } else {
        if (valueMirror.isSubtypeOf(member.returnType)) return true;
      }
    }
    return false;
  }

  /**
   * Check whether the [invocation] is consistent with the [member] mirror.
   */
  bool _checkDeclaration(
      Invocation invocation, mirrors.DeclarationMirror member) {
    if (member is mirrors.VariableMirror || (member as dynamic).isGetter) {
      // TODO(jacobr): actually check method types against the function type
      // returned by the getter or field.
      return true;
    }
    var parameters = (member as dynamic).parameters;
    var positionalArguments = invocation.positionalArguments;
    // Too many arguments
    if (parameters.length < positionalArguments.length) return false;
    // Too few required arguments.
    if (parameters.length > positionalArguments.length &&
        !parameters[positionalArguments.length].isOptional) return false;
    for (var i = 0; i < positionalArguments.length; i++) {
      if (parameters[i].isNamed) {
        // Not enough positional arguments.
        return false;
      }
      if (!_checkType(invocation.positionalArguments[i], parameters[i].type))
        return false;
    }
    if (invocation.namedArguments.isNotEmpty) {
      var startNamed;
      for (startNamed = parameters.length - 1; startNamed >= 0; startNamed--) {
        if (!parameters[startNamed].isNamed) break;
      }
      startNamed++;

      // TODO(jacobr): we are unneccessarily using an O(n^2) algorithm here.
      // If we have JS APIs with a lange number of named parameters we should
      // optimize this. Either use a HashSet or invert this, walking over
      // parameters, querying invocation, and making sure we match
      //invocation.namedArguments.size keys.
      for (var name in invocation.namedArguments.keys) {
        bool match = false;
        for (var j = startNamed; j < parameters.length; j++) {
          var p = parameters[j];
          if (p.simpleName == name) {
            if (!_checkType(
                invocation.namedArguments[name], parameters[j].type))
              return false;
            match = true;
            break;
          }
        }
        if (match == false) return false;
      }
    }
    return true;
  }

  bool checkInvocation(Invocation invocation) {
    for (var member in _members) {
      if (_checkDeclaration(invocation, member)) return true;
    }
    return false;
  }

  void add(mirrors.DeclarationMirror mirror) {
    _members.add(mirror);
  }

  final List<mirrors.DeclarationMirror> _members;
}

/**
 * Temporary method that we hope to remove at some point. This method should
 * generally only be called by machine generated code.
 */
@Deprecated("Internal Use Only")
void registerJsInterfaces([List<Type> classes]) {
  // This method is now obsolete in Dartium.
}

void _registerJsInterfaces(List<Type> classes) {
  for (Type type in classes) {
    mirrors.ClassMirror typeMirror = mirrors.reflectType(type);
    typeMirror.declarations.forEach((symbol, declaration) {
      if (declaration is mirrors.MethodMirror ||
          declaration is mirrors.VariableMirror && !declaration.isStatic) {
        bool treatAsGetter = false;
        bool treatAsSetter = false;
        if (declaration is mirrors.VariableMirror) {
          treatAsGetter = true;
          if (!declaration.isConst && !declaration.isFinal) {
            treatAsSetter = true;
          }
        } else {
          if (declaration.isGetter) {
            treatAsGetter = true;
          } else if (declaration.isSetter) {
            treatAsSetter = true;
          } else if (!declaration.isConstructor) {
            _allowedMethods
                .putIfAbsent(symbol, () => new _DeclarationSet())
                .add(declaration);
          }
        }
        if (treatAsGetter) {
          _allowedGetters
              .putIfAbsent(symbol, () => new _DeclarationSet())
              .add(declaration);
          _allowedMethods
              .putIfAbsent(symbol, () => new _DeclarationSet())
              .add(declaration);
        }
        if (treatAsSetter) {
          _allowedSetters
              .putIfAbsent(symbol, () => new _DeclarationSet())
              .add(declaration);
        }
      }
    });
  }
}

_finalizeJsInterfaces() native "Js_finalizeJsInterfaces";

String _getJsName(mirrors.DeclarationMirror mirror) {
  if (_atJsType != null) {
    for (var annotation in mirror.metadata) {
      if (annotation.type.reflectedType == _atJsType) {
        try {
          var name = annotation.reflectee.name;
          return name != null ? name : "";
        } catch (e) {}
      }
    }
  }
  return null;
}

bool _isAnonymousClass(mirrors.ClassMirror mirror) {
  for (var annotation in mirror.metadata) {
    if (mirrors.MirrorSystem.getName(annotation.type.simpleName) ==
        "_Anonymous") {
      mirrors.LibraryMirror library = annotation.type.owner;
      var uri = library.uri;
      // make sure the annotation is from package://js
      if (uri.scheme == 'package' && uri.path == 'js/js.dart') {
        return true;
      }
    }
  }
  return false;
}

bool _hasJsName(mirrors.DeclarationMirror mirror) {
  if (_atJsType != null) {
    for (var annotation in mirror.metadata) {
      if (annotation.type.reflectedType == _atJsType) {
        return true;
      }
    }
  }
  return false;
}

var _domNameType;

bool hasDomName(mirrors.DeclarationMirror mirror) {
  var location = mirror.location;
  if (location == null || location.sourceUri.scheme != 'dart') return false;
  for (var annotation in mirror.metadata) {
    if (mirrors.MirrorSystem.getName(annotation.type.simpleName) == "DomName") {
      // We can't make sure the annotation is in dart: as Dartium believes it
      // is file://dart/sdk/lib/html/html_common/metadata.dart
      // instead of a proper dart: location.
      return true;
    }
  }
  return false;
}

_getJsMemberName(mirrors.DeclarationMirror mirror) {
  var name = _getJsName(mirror);
  return name == null || name.isEmpty
      ? _stripReservedNamePrefix(_getDeclarationName(mirror))
      : name;
}

// TODO(jacobr): handle setters correctyl.
String _getDeclarationName(mirrors.DeclarationMirror declaration) {
  var name = mirrors.MirrorSystem.getName(declaration.simpleName);
  if (declaration is mirrors.MethodMirror && declaration.isSetter) {
    assert(name.endsWith("="));
    name = name.substring(0, name.length - 1);
  }
  return name;
}

final _JS_LIBRARY_PREFIX = "js_library";
final _UNDEFINED_VAR = "_UNDEFINED_JS_CONST";

String _accessJsPath(String path) => _accessJsPathHelper(path.split("."));

String _accessJsPathHelper(Iterable<String> parts) {
  var sb = new StringBuffer();
  sb
    ..write('${_JS_LIBRARY_PREFIX}.JsNative.getProperty(' * parts.length)
    ..write("${_JS_LIBRARY_PREFIX}.context");
  for (var p in parts) {
    sb.write(", ${_escapeString(p)})");
  }
  return sb.toString();
}

// TODO(jacobr): remove these helpers and add JsNative.setPropertyDotted,
// getPropertyDotted, and callMethodDotted helpers that would be simpler
// and more efficient.
String _accessJsPathSetter(String path) {
  var parts = path.split(".");
  return "${_JS_LIBRARY_PREFIX}.JsNative.setProperty(${_accessJsPathHelper(parts.getRange(0, parts.length - 1))
      }, ${_escapeString(parts.last)}, v)";
}

String _accessJsPathCallMethodHelper(String path) {
  var parts = path.split(".");
  return "${_JS_LIBRARY_PREFIX}.JsNative.callMethod(${_accessJsPathHelper(parts.getRange(0, parts.length - 1))
      }, ${_escapeString(parts.last)},";
}

@Deprecated("Internal Use Only")
void addMemberHelper(
    mirrors.MethodMirror declaration, String path, StringBuffer sb,
    {bool isStatic: false, String memberName}) {
  if (!declaration.isConstructor) {
    var jsName = _getJsMemberName(declaration);
    path = (path != null && path.isNotEmpty) ? "${path}.${jsName}" : jsName;
  }
  var name = memberName != null ? memberName : _getDeclarationName(declaration);
  if (declaration.isConstructor) {
    sb.write("factory");
  } else if (isStatic) {
    sb.write("static");
  } else {
    sb.write("@patch");
  }
  sb.write(" ");
  if (declaration.isGetter) {
    sb.write("get $name => ${_accessJsPath(path)};");
  } else if (declaration.isSetter) {
    sb.write("set $name(v) {\n"
        "  ${_JS_LIBRARY_PREFIX}.safeForTypedInterop(v);\n"
        "  return ${_accessJsPathSetter(path)};\n"
        "}\n");
  } else {
    sb.write("$name(");
    bool hasOptional = false;
    int i = 0;
    var args = <String>[];
    for (var p in declaration.parameters) {
      assert(!p.isNamed); // TODO(jacobr): throw.
      assert(!p.hasDefaultValue);
      if (i > 0) {
        sb.write(", ");
      }
      if (p.isOptional && !hasOptional) {
        sb.write("[");
        hasOptional = true;
      }
      var arg = "p$i";
      args.add(arg);
      sb.write(arg);
      if (p.isOptional) {
        sb.write("=${_UNDEFINED_VAR}");
      }
      i++;
    }
    if (hasOptional) {
      sb.write("]");
    }
    // TODO(jacobr):
    sb.write(") {\n");
    for (var arg in args) {
      sb.write("  ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($arg);\n");
    }
    sb.write("  return ");
    if (declaration.isConstructor) {
      sb.write("${_JS_LIBRARY_PREFIX}.JsNative.callConstructor(");
      sb..write(_accessJsPath(path))..write(",");
    } else {
      sb.write(_accessJsPathCallMethodHelper(path));
    }
    sb.write("[${args.join(",")}]");

    if (hasOptional) {
      sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()");
    }
    sb.write(");");
    sb.write("}\n");
  }
  sb.write("\n");
}

bool _isExternal(mirrors.MethodMirror mirror) {
  // This try-catch block is a workaround for BUG:24834.
  try {
    return mirror.isExternal;
  } catch (e) {}
  return false;
}

List<String> _generateExternalMethods(
    List<String> libraryPaths, bool useCachedPatches) {
  var staticCodegen = <String>[];

  if (libraryPaths.length == 0) {
    mirrors.currentMirrorSystem().libraries.forEach((uri, library) {
      var library_name = "${uri.scheme}:${uri.path}";
      if (useCachedPatches && cached_patches.containsKey(library_name)) {
        // Use the pre-generated patch files for DOM dart:nnnn libraries.
        var patch = cached_patches[library_name];
        staticCodegen.addAll(patch);
      } else if (_hasJsName(library)) {
        // Library marked with @JS
        _generateLibraryCodegen(uri, library, staticCodegen);
      } else if (!useCachedPatches) {
        // Can't use the cached patches file, instead this is a signal to generate
        // the patches for this file.
        _generateLibraryCodegen(uri, library, staticCodegen);
      }
    }); // End of library foreach
  } else {
    // Used to generate cached_patches.dart file for all IDL generated dart:
    // files to the WebKit DOM.
    for (var library_name in libraryPaths) {
      var parts = library_name.split(':');
      var uri = new Uri(scheme: parts[0], path: parts[1]);
      var library = mirrors.currentMirrorSystem().libraries[uri];
      _generateLibraryCodegen(uri, library, staticCodegen);
    }
  }

  return staticCodegen;
}

_generateLibraryCodegen(uri, library, staticCodegen) {
  // Is it a dart generated library?
  var dartLibrary = uri.scheme == 'dart';

  var sb = new StringBuffer();
  String jsLibraryName = _getJsName(library);

  // Sort by patch file by its declaration name.
  var sortedDeclKeys = library.declarations.keys.toList();
  sortedDeclKeys.sort((a, b) => mirrors.MirrorSystem
      .getName(a)
      .compareTo(mirrors.MirrorSystem.getName(b)));

  sortedDeclKeys.forEach((name) {
    var declaration = library.declarations[name];
    if (declaration is mirrors.MethodMirror) {
      if ((_hasJsName(declaration) || jsLibraryName != null) &&
          _isExternal(declaration)) {
        addMemberHelper(declaration, jsLibraryName, sb);
      }
    } else if (declaration is mirrors.ClassMirror) {
      mirrors.ClassMirror clazz = declaration;
      var isDom = dartLibrary ? hasDomName(clazz) : false;
      var isJsInterop = _hasJsName(clazz);
      if (isDom || isJsInterop) {
        // TODO(jacobr): verify class implements JavaScriptObject.
        var className = mirrors.MirrorSystem.getName(clazz.simpleName);
        bool isPrivateUserDefinedClass =
            className.startsWith('_') && !dartLibrary;
        var classNameImpl = '${className}Impl';
        var sbPatch = new StringBuffer();
        if (isJsInterop) {
          String jsClassName = _getJsMemberName(clazz);

          jsInterfaceTypes.add(clazz);
          clazz.declarations.forEach((name, declaration) {
            if (declaration is! mirrors.MethodMirror ||
                !_isExternal(declaration)) return;
            if (declaration.isFactoryConstructor && _isAnonymousClass(clazz)) {
              sbPatch.write("  factory ${className}(");
              int i = 0;
              var args = <String>[];
              for (var p in declaration.parameters) {
                args.add(mirrors.MirrorSystem.getName(p.simpleName));
                i++;
              }
              if (args.isNotEmpty) {
                sbPatch
                  ..write('{')
                  ..write(
                      args.map((name) => '$name:${_UNDEFINED_VAR}').join(", "))
                  ..write('}');
              }
              sbPatch.write(") {\n"
                  "    var ret = ${_JS_LIBRARY_PREFIX}.JsNative.newObject();\n");
              i = 0;
              for (var p in declaration.parameters) {
                assert(p.isNamed); // TODO(jacobr): throw.
                var name = args[i];
                var jsName = _stripReservedNamePrefix(
                    mirrors.MirrorSystem.getName(p.simpleName));
                sbPatch.write("    if($name != ${_UNDEFINED_VAR}) {\n"
                    "      ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($name);\n"
                    "      ${_JS_LIBRARY_PREFIX}.JsNative.setProperty(ret, ${_escapeString(jsName)}, $name);\n"
                    "    }\n");
                i++;
              }

              sbPatch.write("  return ret;"
                  "}\n");
            } else if (declaration.isConstructor ||
                declaration.isFactoryConstructor) {
              sbPatch.write("  ");
              addMemberHelper(
                  declaration,
                  (jsLibraryName != null && jsLibraryName.isNotEmpty)
                      ? "${jsLibraryName}.${jsClassName}"
                      : jsClassName,
                  sbPatch,
                  isStatic: true,
                  memberName: className);
            }
          }); // End of clazz.declarations.forEach

          clazz.staticMembers.forEach((memberName, member) {
            if (_isExternal(member)) {
              sbPatch.write("  ");
              addMemberHelper(
                  member,
                  (jsLibraryName != null && jsLibraryName.isNotEmpty)
                      ? "${jsLibraryName}.${jsClassName}"
                      : jsClassName,
                  sbPatch,
                  isStatic: true);
            }
          });
        }
        if (isDom) {
          sbPatch.write(
              "  static Type get instanceRuntimeType => ${classNameImpl};\n");
        }
        if (isPrivateUserDefinedClass) {
          sb.write("""
class ${escapePrivateClassPrefix}${className} implements $className {}
""");
        }

        if (sbPatch.isNotEmpty) {
          var typeVariablesClause = '';
          if (!clazz.typeVariables.isEmpty) {
            typeVariablesClause =
                '<${clazz.typeVariables.map((m) => mirrors.MirrorSystem.getName(m.simpleName)).join(',')}>';
          }
          sb.write("""
@patch class $className$typeVariablesClause {
$sbPatch
}
""");
          if (isDom) {
            sb.write("""
class $classNameImpl$typeVariablesClause extends $className implements ${_JS_LIBRARY_PREFIX}.JSObjectInterfacesDom {
  ${classNameImpl}.internal_() : super.internal_();
  get runtimeType => $className;
  toString() => super.toString();
}
""");
          }
        }
      }
    }
  });
  if (sb.isNotEmpty) {
    staticCodegen
      ..add(uri.toString())
      ..add("${uri}_js_interop_patch.dart")
      ..add("""
import 'dart:js' as ${_JS_LIBRARY_PREFIX};

/**
 * Placeholder object for cases where we need to determine exactly how many
 * args were passed to a function.
 */
const ${_UNDEFINED_VAR} = const Object();

${sb}
""");
  }
}

// Remember the @JS type to compare annotation type.
var _atJsType = -1;

void setupJsTypeCache() {
  // Cache the @JS Type.
  if (_atJsType == -1) {
    var uri = new Uri(scheme: "package", path: "js/js.dart");
    var jsLibrary = mirrors.currentMirrorSystem().libraries[uri];
    if (jsLibrary != null) {
      // @ JS used somewhere.
      var jsDeclaration = jsLibrary.declarations[new Symbol("JS")];
      _atJsType = jsDeclaration.reflectedType;
    } else {
      // @ JS not used in any library.
      _atJsType = null;
    }
  }
}

/**
 * Generates part files defining source code for JSObjectImpl, all DOM classes
 * classes. This codegen  is needed so that type checks for all registered
 * JavaScript interop classes pass.
 * If genCachedPatches is true then the patch files don't exist this is a special
 * signal to generate and emit the patches to stdout to be captured and put into
 * the file sdk/lib/js/dartium/cached_patches.dart
 */
List<String> _generateInteropPatchFiles(
    List<String> libraryPaths, genCachedPatches) {
  // Cache the @JS Type.
  if (_atJsType == -1) setupJsTypeCache();

  var ret =
      _generateExternalMethods(libraryPaths, genCachedPatches ? false : true);
  var libraryPrefixes = new Map<mirrors.LibraryMirror, String>();
  var prefixNames = new Set<String>();
  var sb = new StringBuffer();

  var implements = <String>[];
  var implementsArray = <String>[];
  var implementsDom = <String>[];
  var listMirror = mirrors.reflectType(List);
  var functionMirror = mirrors.reflectType(Function);
  var jsObjectMirror = mirrors.reflectType(JSObject);

  for (var typeMirror in jsInterfaceTypes) {
    mirrors.LibraryMirror libraryMirror = typeMirror.owner;
    var location = libraryMirror.location;
    var dartLibrary = location != null && location.sourceUri.scheme == 'dart';

    var prefixName;
    if (libraryPrefixes.containsKey(libraryMirror)) {
      prefixName = libraryPrefixes[libraryMirror];
    } else {
      var basePrefixName =
          mirrors.MirrorSystem.getName(libraryMirror.simpleName);
      basePrefixName = basePrefixName.replaceAll('.', '_');
      if (basePrefixName.isEmpty) basePrefixName = "lib";
      prefixName = basePrefixName;
      var i = 1;
      while (prefixNames.contains(prefixName)) {
        prefixName = '$basePrefixName$i';
        i++;
      }
      prefixNames.add(prefixName);
      libraryPrefixes[libraryMirror] = prefixName;
    }
    var isArray = typeMirror.isSubtypeOf(listMirror);
    var isFunction = typeMirror.isSubtypeOf(functionMirror);
    var isJSObject = typeMirror.isSubtypeOf(jsObjectMirror);
    var className = mirrors.MirrorSystem.getName(typeMirror.simpleName);
    var isPrivateUserDefinedClass = className.startsWith('_') && !dartLibrary;
    if (isPrivateUserDefinedClass)
      className = '${escapePrivateClassPrefix}${className}';
    var fullName = '${prefixName}.${className}';
    (isArray ? implementsArray : implements).add(fullName);
    if (!isArray && !isFunction && !isJSObject) {
      // For DOM classes we need to be a bit more conservative at tagging them
      // as implementing JS inteorp classes risks strange unintended
      // consequences as unrleated code may have instanceof checks.  Checking
      // for isJSObject ensures we do not accidentally pull in existing
      // dart:html classes as they all have JSObject as a base class.
      // Note that methods from these classes can still be called on a
      // dart:html instance but checked mode type checks will fail. This is
      // not ideal but is better than causing strange breaks in existing
      // code that uses dart:html.
      // TODO(jacobr): consider throwing compile time errors if @JS classes
      // extend JSObject as that case cannot be safely handled in Dartium.
      implementsDom.add(fullName);
    }
  }
  libraryPrefixes.forEach((libraryMirror, prefix) {
    sb.writeln('import "${libraryMirror.uri}" as $prefix;');
  });
  buildImplementsClause(classes) =>
      classes.isEmpty ? "" : "implements ${classes.join(', ')}";
  var implementsClause = buildImplementsClause(implements);
  var implementsClauseDom = buildImplementsClause(implementsDom);
  // TODO(jacobr): only certain classes need to be implemented by
  // JsFunctionImpl.
  var allTypes = []..addAll(implements)..addAll(implementsArray);
  sb.write('''
class JSObjectImpl extends JSObject $implementsClause {
  JSObjectImpl.internal() : super.internal();
}

class JSFunctionImpl extends JSFunction $implementsClause {
  JSFunctionImpl.internal() : super.internal();
}

class JSArrayImpl extends JSArray ${buildImplementsClause(implementsArray)} {
  JSArrayImpl.internal() : super.internal();
}

// Interfaces that are safe to slam on all DOM classes.
// Adding implementsClause would be risky as it could contain Function which
// is likely to break a lot of instanceof checks.
abstract class JSObjectInterfacesDom $implementsClauseDom {
}

@patch class JSObject {
  static Type get instanceRuntimeType => JSObjectImpl;
}

@patch class JSFunction {
  static Type get instanceRuntimeType => JSFunctionImpl;
}

@patch class JSArray {
  static Type get instanceRuntimeType => JSArrayImpl;
}

_registerAllJsInterfaces() {
  _registerJsInterfaces([${allTypes.join(", ")}]);
}

''');
  ret..addAll(["dart:js", "JSInteropImpl.dart", sb.toString()]);
  return ret;
}

// Start of block of helper methods facilitating emulating JavaScript Array
// methods on Dart List objects passed to JavaScript via JS interop.
// TODO(jacobr): match JS more closely.
String _toStringJs(obj) => '$obj';

// TODO(jacobr): this might not exactly match JS semantics but should be
// adequate for now.
int _toIntJs(obj) {
  if (obj is int) return obj;
  if (obj is num) return obj.toInt();
  return num.parse('$obj'.trim(), (_) => 0).toInt();
}

// TODO(jacobr): this might not exactly match JS semantics but should be
// adequate for now.
num _toNumJs(obj) {
  return obj is num ? obj : num.parse('$obj'.trim(), (_) => 0);
}

/// Match the behavior of setting List length in JavaScript with the exception
/// that Dart does not distinguish undefined and null.
_setListLength(List list, rawlen) {
  num len = _toNumJs(rawlen);
  if (len is! int || len < 0) {
    throw new RangeError("Invalid array length");
  }
  if (len > list.length) {
    _arrayExtend(list, len);
  } else if (len < list.length) {
    list.removeRange(len, list.length);
  }
  return rawlen;
}

// TODO(jacobr): should we really bother with this method instead of just
// shallow copying to a JS array and calling the JavaScript join method?
String _arrayJoin(List list, sep) {
  if (sep == null) {
    sep = ",";
  }
  return list.map((e) => e == null ? "" : e.toString()).join(sep.toString());
}

// TODO(jacobr): should we really bother with this method instead of just
// shallow copying to a JS array and using the toString method?
String _arrayToString(List list) => _arrayJoin(list, ",");

int _arrayPush(List list, List args) {
  for (var e in args) {
    list.add(e);
  }
  return list.length;
}

_arrayPop(List list) {
  if (list.length > 0) return list.removeLast();
}

// TODO(jacobr): would it be better to just copy input to a JS List
// and call Array.concat?
List _arrayConcat(List input, List args) {
  var ret = new List.from(input);
  for (var e in args) {
    // TODO(jacobr): technically in ES6 we should use
    // Symbol.isConcatSpreadable to determine whether call addAll. Once v8
    // supports it, we can make all Dart classes implementing Iterable
    // specify isConcatSpreadable and tweak this behavior to allow Iterable.
    if (e is List) {
      ret.addAll(e);
    } else {
      ret.add(e);
    }
  }
  return ret;
}

List _arraySplice(List input, List args) {
  int start = 0;
  if (args.length > 0) {
    var rawStart = _toIntJs(args[0]);
    if (rawStart < 0) {
      start = math.max(0, input.length - rawStart);
    } else {
      start = math.min(input.length, rawStart);
    }
  }
  var end = start;
  if (args.length > 1) {
    var rawDeleteCount = _toIntJs(args[1]);
    if (rawDeleteCount < 0) rawDeleteCount = 0;
    end = math.min(input.length, start + rawDeleteCount);
  }
  var replacement = [];
  var removedElements = input.getRange(start, end).toList();
  if (args.length > 2) {
    replacement = args.getRange(2, args.length);
  }
  input.replaceRange(start, end, replacement);
  return removedElements;
}

List _arrayReverse(List l) {
  for (var i = 0, j = l.length - 1; i < j; i++, j--) {
    var tmp = l[i];
    l[i] = l[j];
    l[j] = tmp;
  }
  return l;
}

_arrayShift(List l) {
  if (l.isEmpty) return null; // Technically we should return undefined.
  return l.removeAt(0);
}

int _arrayUnshift(List l, List args) {
  l.insertAll(0, args);
  return l.length;
}

_arrayExtend(List l, int newLength) {
  for (var i = l.length; i < newLength; i++) {
    // TODO(jacobr): we'd really like to add undefined to better match
    // JavaScript semantics.
    l.add(null);
  }
}

List _arraySort(List l, rawCompare) {
  // TODO(jacobr): alternately we could just copy the Array to JavaScript,
  // invoke the JS sort method and then copy the result back to Dart.
  Comparator compare;
  if (rawCompare == null) {
    compare = (a, b) => _toStringJs(a).compareTo(_toStringJs(b));
  } else if (rawCompare is JsFunction) {
    compare = (a, b) => rawCompare.apply([a, b]);
  } else {
    compare = rawCompare;
  }
  l.sort(compare);
  return l;
}
// End of block of helper methods to emulate JavaScript Array methods on Dart List.

/**
 * Can be called to provide a predictable point where no more JS interfaces can
 * be added. Creating an instance of JsObject will also automatically trigger
 * all JsObjects to be finalized.
 */
@Deprecated("Internal Use Only")
void finalizeJsInterfaces() {
  if (_finalized == true) {
    throw 'JSInterop class registration already finalized';
  }
  _finalizeJsInterfaces();
}

JsObject _cachedContext;

JsObject get _context native "Js_context_Callback";

bool get _finalized native "Js_interfacesFinalized_Callback";

JsObject get context {
  if (_cachedContext == null) {
    _cachedContext = _context;
  }
  return _cachedContext;
}

_lookupType(o, bool isCrossFrame, bool isElement) {
  try {
    var type = html_common.lookupType(o, isElement);
    var typeMirror = mirrors.reflectType(type);
    var legacyInteropConvertToNative =
        typeMirror.isSubtypeOf(mirrors.reflectType(html.Blob)) ||
            typeMirror.isSubtypeOf(mirrors.reflectType(html.Event)) ||
            typeMirror.isSubtypeOf(mirrors.reflectType(indexed_db.KeyRange)) ||
            typeMirror.isSubtypeOf(mirrors.reflectType(html.ImageData)) ||
            typeMirror.isSubtypeOf(mirrors.reflectType(html.Node)) ||
//        TypedData is removed from this list as it is converted directly
//        rather than flowing through the interceptor code path.
//        typeMirror.isSubtypeOf(mirrors.reflectType(typed_data.TypedData)) ||
            typeMirror.isSubtypeOf(mirrors.reflectType(html.Window));
    if (isCrossFrame &&
        !typeMirror.isSubtypeOf(mirrors.reflectType(html.Window))) {
      // TODO(jacobr): evaluate using the true cross frame Window class, etc.
      // as well as triggering that legacy JS Interop returns raw JsObject
      // instances.
      legacyInteropConvertToNative = false;
    }
    return [type, legacyInteropConvertToNative];
  } catch (e) {}
  return [JSObject.instanceRuntimeType, false];
}

/**
 * Base class for both the legacy JsObject class and the modern JSObject class.
 * This allows the JsNative utility class tobehave identically whether it is
 * called on a JsObject or a JSObject.
 */
class _JSObjectBase extends NativeFieldWrapperClass2 {
  String _toString() native "JSObject_toString";
  _callMethod(String name, List args) native "JSObject_callMethod";
  _operator_getter(String property) native "JSObject_[]";
  _operator_setter(String property, value) native "JSObject_[]=";
  bool _hasProperty(String property) native "JsObject_hasProperty";
  bool _instanceof(/*JsFunction|JSFunction*/ type) native "JsObject_instanceof";

  int get hashCode native "JSObject_hashCode";
}

/**
 * Proxies a JavaScript object to Dart.
 *
 * The properties of the JavaScript object are accessible via the `[]` and
 * `[]=` operators. Methods are callable via [callMethod].
 */
class JsObject extends _JSObjectBase {
  JsObject.internal();

  /**
   * Constructs a new JavaScript object from [constructor] and returns a proxy
   * to it.
   */
  factory JsObject(JsFunction constructor, [List arguments]) {
    try {
      return _create(constructor, arguments);
    } catch (e) {
      // Re-throw any errors (returned as a string) as a DomException.
      throw new html.DomException.jsInterop(e);
    }
  }

  static JsObject _create(JsFunction constructor, arguments)
      native "JsObject_constructorCallback";

  /**
   * Constructs a [JsObject] that proxies a native Dart object; _for expert use
   * only_.
   *
   * Use this constructor only if you wish to get access to JavaScript
   * properties attached to a browser host object, such as a Node or Blob, that
   * is normally automatically converted into a native Dart object.
   *
   * An exception will be thrown if [object] either is `null` or has the type
   * `bool`, `num`, or `String`.
   */
  factory JsObject.fromBrowserObject(object) {
    if (object is num || object is String || object is bool || object == null) {
      throw new ArgumentError("object cannot be a num, string, bool, or null");
    }
    if (object is JsObject) return object;
    return _fromBrowserObject(object);
  }

  /**
   * Recursively converts a JSON-like collection of Dart objects to a
   * collection of JavaScript objects and returns a [JsObject] proxy to it.
   *
   * [object] must be a [Map] or [Iterable], the contents of which are also
   * converted. Maps and Iterables are copied to a new JavaScript object.
   * Primitives and other transferrable values are directly converted to their
   * JavaScript type, and all other objects are proxied.
   */
  factory JsObject.jsify(object) {
    if ((object is! Map) && (object is! Iterable)) {
      throw new ArgumentError("object must be a Map or Iterable");
    }
    return _jsify(object);
  }

  static JsObject _jsify(object) native "JsObject_jsify";

  static JsObject _fromBrowserObject(object)
      native "JsObject_fromBrowserObject";

  /**
   * Returns the value associated with [property] from the proxied JavaScript
   * object.
   *
   * The type of [property] must be either [String] or [num].
   */
  operator [](property) {
    try {
      return _operator_getterLegacy(property);
    } catch (e) {
      // Re-throw any errors (returned as a string) as a DomException.
      throw new html.DomException.jsInterop(e);
    }
  }

  _operator_getterLegacy(property) native "JsObject_[]Legacy";

  /**
   * Sets the value associated with [property] on the proxied JavaScript
   * object.
   *
   * The type of [property] must be either [String] or [num].
   */
  operator []=(property, value) {
    try {
      _operator_setterLegacy(property, value);
    } catch (e) {
      // Re-throw any errors (returned as a string) as a DomException.
      throw new html.DomException.jsInterop(e);
    }
  }

  _operator_setterLegacy(property, value) native "JsObject_[]=Legacy";

  int get hashCode native "JsObject_hashCode";

  operator ==(other) {
    if (other is! JsObject && other is! JSObject) return false;
    return _identityEquality(this, other);
  }

  static bool _identityEquality(a, b) native "JsObject_identityEquality";

  /**
   * Returns `true` if the JavaScript object contains the specified property
   * either directly or though its prototype chain.
   *
   * This is the equivalent of the `in` operator in JavaScript.
   */
  bool hasProperty(String property) => _hasProperty(property);

  /**
   * Removes [property] from the JavaScript object.
   *
   * This is the equivalent of the `delete` operator in JavaScript.
   */
  void deleteProperty(String property) native "JsObject_deleteProperty";

  /**
   * Returns `true` if the JavaScript object has [type] in its prototype chain.
   *
   * This is the equivalent of the `instanceof` operator in JavaScript.
   */
  bool instanceof(JsFunction type) => _instanceof(type);

  /**
   * Returns the result of the JavaScript objects `toString` method.
   */
  String toString() {
    try {
      return _toString();
    } catch (e) {
      return super.toString();
    }
  }

  String _toString() native "JsObject_toString";

  /**
   * Calls [method] on the JavaScript object with the arguments [args] and
   * returns the result.
   *
   * The type of [method] must be either [String] or [num].
   */
  callMethod(String method, [List args]) {
    try {
      return _callMethodLegacy(method, args);
    } catch (e) {
      if (hasProperty(method)) {
        // Return a DomException if DOM call returned an error.
        throw new html.DomException.jsInterop(e);
      } else {
        throw new NoSuchMethodError(this, new Symbol(method), args, null);
      }
    }
  }

  _callMethodLegacy(String name, List args) native "JsObject_callMethodLegacy";
}

/// Base class for all JS objects used through dart:html and typed JS interop.
@Deprecated("Internal Use Only")
class JSObject extends _JSObjectBase {
  JSObject.internal() {}
  external static Type get instanceRuntimeType;

  /**
   * Returns the result of the JavaScript objects `toString` method.
   */
  String toString() {
    try {
      return _toString();
    } catch (e) {
      return super.toString();
    }
  }

  noSuchMethod(Invocation invocation) {
    throwError() {
      super.noSuchMethod(invocation);
    }

    String name = _stripReservedNamePrefix(
        mirrors.MirrorSystem.getName(invocation.memberName));
    argsSafeForTypedInterop(invocation.positionalArguments);
    if (invocation.isGetter) {
      if (CHECK_JS_INVOCATIONS) {
        var matches = _allowedGetters[invocation.memberName];
        if (matches == null &&
            !_allowedMethods.containsKey(invocation.memberName)) {
          throwError();
        }
        var ret = _operator_getter(name);
        if (matches != null) return ret;
        if (ret is Function ||
            (ret is JsFunction /* shouldn't be needed in the future*/) &&
                _allowedMethods.containsKey(invocation.memberName))
          return ret; // Warning: we have not bound "this"... we could type check on the Function but that is of little value in Dart.
        throwError();
      } else {
        // TODO(jacobr): should we throw if the JavaScript object doesn't have the property?
        return _operator_getter(name);
      }
    } else if (invocation.isSetter) {
      if (CHECK_JS_INVOCATIONS) {
        var matches = _allowedSetters[invocation.memberName];
        if (matches == null || !matches.checkInvocation(invocation))
          throwError();
      }
      assert(name.endsWith("="));
      name = name.substring(0, name.length - 1);
      return _operator_setter(name, invocation.positionalArguments.first);
    } else {
      // TODO(jacobr): also allow calling getters that look like functions.
      var matches;
      if (CHECK_JS_INVOCATIONS) {
        matches = _allowedMethods[invocation.memberName];
        if (matches == null || !matches.checkInvocation(invocation))
          throwError();
      }
      var ret = _callMethod(name, _buildArgs(invocation));
      if (CHECK_JS_INVOCATIONS) {
        if (!matches._checkReturnType(ret)) {
          html.window.console.error("Return value for method: ${name} is "
              "${ret.runtimeType} which is inconsistent with all typed "
              "JS interop definitions for method ${name}.");
        }
      }
      return ret;
    }
  }
}

@Deprecated("Internal Use Only")
class JSArray extends JSObject with ListMixin {
  JSArray.internal() : super.internal();
  external static Type get instanceRuntimeType;

  // Reuse JsArray_length as length behavior is unchanged.
  int get length native "JsArray_length";

  set length(int length) {
    _operator_setter('length', length);
  }

  _checkIndex(int index, {bool insert: false}) {
    int length = insert ? this.length + 1 : this.length;
    if (index is int && (index < 0 || index >= length)) {
      throw new RangeError.range(index, 0, length);
    }
  }

  _checkRange(int start, int end) {
    int cachedLength = this.length;
    if (start < 0 || start > cachedLength) {
      throw new RangeError.range(start, 0, cachedLength);
    }
    if (end < start || end > cachedLength) {
      throw new RangeError.range(end, start, cachedLength);
    }
  }

  _indexed_getter(int index) native "JSArray_indexed_getter";
  _indexed_setter(int index, o) native "JSArray_indexed_setter";

  // Methods required by ListMixin

  operator [](index) {
    if (index is int) {
      _checkIndex(index);
    }

    return _indexed_getter(index);
  }

  void operator []=(int index, value) {
    _checkIndex(index);
    _indexed_setter(index, value);
  }
}

@Deprecated("Internal Use Only")
class JSFunction extends JSObject implements Function {
  JSFunction.internal() : super.internal();

  external static Type get instanceRuntimeType;

  call(
      [a1 = _UNDEFINED,
      a2 = _UNDEFINED,
      a3 = _UNDEFINED,
      a4 = _UNDEFINED,
      a5 = _UNDEFINED,
      a6 = _UNDEFINED,
      a7 = _UNDEFINED,
      a8 = _UNDEFINED,
      a9 = _UNDEFINED,
      a10 = _UNDEFINED]) {
    return _apply(
        _stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));
  }

  noSuchMethod(Invocation invocation) {
    if (invocation.isMethod && invocation.memberName == #call) {
      return _apply(_buildArgs(invocation));
    }
    return super.noSuchMethod(invocation);
  }

  dynamic _apply(List args, {thisArg}) native "JSFunction_apply";

  static JSFunction _createWithThis(Function f)
      native "JSFunction_createWithThis";
  static JSFunction _create(Function f) native "JSFunction_create";
}

// JavaScript interop methods that do not automatically wrap to dart:html types.
// Warning: this API is not exposed to dart:js.
// TODO(jacobr): rename to JSNative and make at least part of this API public.
@Deprecated("Internal Use Only")
class JsNative {
  static JSObject jsify(object) native "JSObject_jsify";
  static JSObject newObject() native "JSObject_newObject";
  static JSArray newArray() native "JSObject_newArray";

  static hasProperty(_JSObjectBase o, name) => o._hasProperty(name);
  static getProperty(_JSObjectBase o, name) => o._operator_getter(name);
  static setProperty(_JSObjectBase o, name, value) =>
      o._operator_setter(name, value);
  static callMethod(_JSObjectBase o, String method, List args) =>
      o._callMethod(method, args);
  static instanceof(_JSObjectBase o, /*JsFunction|JSFunction*/ type) =>
      o._instanceof(type);
  static callConstructor0(_JSObjectBase constructor)
      native "JSNative_callConstructor0";
  static callConstructor(_JSObjectBase constructor, List args)
      native "JSNative_callConstructor";

  static toTypedObject(JsObject o) native "JSNative_toTypedObject";

  /**
   * Same behavior as new JsFunction.withThis except that JavaScript "this" is not
   * wrapped.
   */
  static JSFunction withThis(Function f) native "JsFunction_withThisNoWrap";
}

/**
 * Proxies a JavaScript Function object.
 */
class JsFunction extends JsObject {
  JsFunction.internal() : super.internal();

  /**
   * Returns a [JsFunction] that captures its 'this' binding and calls [f]
   * with the value of this passed as the first argument.
   */
  factory JsFunction.withThis(Function f) => _withThis(f);

  /**
   * Invokes the JavaScript function with arguments [args]. If [thisArg] is
   * supplied it is the value of `this` for the invocation.
   */
  dynamic apply(List args, {thisArg}) => _apply(args, thisArg: thisArg);

  dynamic _apply(List args, {thisArg}) native "JsFunction_apply";

  /**
   * Internal only version of apply which uses debugger proxies of Dart objects
   * rather than opaque handles. This method is private because it cannot be
   * efficiently implemented in Dart2Js so should only be used by internal
   * tools.
   */
  _applyDebuggerOnly(List args, {thisArg})
      native "JsFunction_applyDebuggerOnly";

  static JsFunction _withThis(Function f) native "JsFunction_withThis";
}

/**
 * A [List] proxying a JavaScript Array.
 */
class JsArray<E> extends JsObject with ListMixin<E> {
  JsArray.internal() : super.internal();

  factory JsArray() => _newJsArray();

  static JsArray _newJsArray() native "JsArray_newJsArray";

  factory JsArray.from(Iterable<E> other) =>
      _newJsArrayFromSafeList(new List.from(other));

  static JsArray _newJsArrayFromSafeList(List list)
      native "JsArray_newJsArrayFromSafeList";

  _checkIndex(int index, {bool insert: false}) {
    int length = insert ? this.length + 1 : this.length;
    if (index is int && (index < 0 || index >= length)) {
      throw new RangeError.range(index, 0, length);
    }
  }

  _checkRange(int start, int end) {
    int cachedLength = this.length;
    if (start < 0 || start > cachedLength) {
      throw new RangeError.range(start, 0, cachedLength);
    }
    if (end < start || end > cachedLength) {
      throw new RangeError.range(end, start, cachedLength);
    }
  }

  // Methods required by ListMixin

  E operator [](index) {
    if (index is int) {
      _checkIndex(index);
    }

    return super[index];
  }

  void operator []=(index, E value) {
    if (index is int) {
      _checkIndex(index);
    }
    super[index] = value;
  }

  int get length native "JsArray_length";

  set length(int length) {
    super['length'] = length;
  }

  // Methods overridden for better performance

  void add(E value) {
    callMethod('push', [value]);
  }

  void addAll(Iterable<E> iterable) {
    // TODO(jacobr): this can be optimized slightly.
    callMethod('push', new List.from(iterable));
  }

  void insert(int index, E element) {
    _checkIndex(index, insert: true);
    callMethod('splice', [index, 0, element]);
  }

  E removeAt(int index) {
    _checkIndex(index);
    return callMethod('splice', [index, 1])[0];
  }

  E removeLast() {
    if (length == 0) throw new RangeError(-1);
    return callMethod('pop');
  }

  void removeRange(int start, int end) {
    _checkRange(start, end);
    callMethod('splice', [start, end - start]);
  }

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    _checkRange(start, end);
    int length = end - start;
    if (length == 0) return;
    if (skipCount < 0) throw new ArgumentError(skipCount);
    var args = [start, length]..addAll(iterable.skip(skipCount).take(length));
    callMethod('splice', args);
  }

  void sort([int compare(E a, E b)]) {
    callMethod('sort', [compare]);
  }
}

/**
 * Placeholder object for cases where we need to determine exactly how many
 * args were passed to a function.
 */
const _UNDEFINED = const Object();

// TODO(jacobr): this method is a hack to work around the lack of proper dart
// support for varargs methods.
List _stripUndefinedArgs(List args) =>
    args.takeWhile((i) => i != _UNDEFINED).toList();

/**
 * Check that that if [arg] is a [Function] it is safe to pass to JavaScript.
 * To make a function safe, call [allowInterop] or [allowInteropCaptureThis].
 */
@Deprecated("Internal Use Only")
safeForTypedInterop(arg) {
  if (CHECK_JS_INVOCATIONS && arg is Function && arg is! JSFunction) {
    throw new ArgumentError(
        "Attempt to pass Function '$arg' to JavaScript via without calling allowInterop or allowInteropCaptureThis");
  }
}

/**
 * Check that that if any elements of [args] are [Function] it is safe to pass
 * to JavaScript. To make a function safe, call [allowInterop] or
 * [allowInteropCaptureThis].
 */
@Deprecated("Internal Use Only")
void argsSafeForTypedInterop(Iterable args) {
  for (var arg in args) {
    safeForTypedInterop(arg);
  }
}

/**
 * Returns a method that can be called with an arbitrary number (for n less
 * than 11) of arguments without violating Dart type checks.
 */
Function _wrapAsDebuggerVarArgsFunction(JsFunction jsFunction) => (
        [a1 = _UNDEFINED,
        a2 = _UNDEFINED,
        a3 = _UNDEFINED,
        a4 = _UNDEFINED,
        a5 = _UNDEFINED,
        a6 = _UNDEFINED,
        a7 = _UNDEFINED,
        a8 = _UNDEFINED,
        a9 = _UNDEFINED,
        a10 = _UNDEFINED]) =>
    jsFunction._applyDebuggerOnly(
        _stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));

/// Returns a wrapper around function [f] that can be called from JavaScript
/// using the package:js Dart-JavaScript interop.
///
/// For performance reasons in Dart2Js, by default Dart functions cannot be
/// passed directly to JavaScript unless this method is called to create
/// a Function compatible with both Dart and JavaScript.
/// Calling this method repeatedly on a function will return the same function.
/// The [Function] returned by this method can be used from both Dart and
/// JavaScript. We may remove the need to call this method completely in the
/// future if Dart2Js is refactored so that its function calling conventions
/// are more compatible with JavaScript.
Function/*=F*/ allowInterop/*<F extends Function>*/(Function/*=F*/ f) {
  if (f is JSFunction) {
    // The function is already a JSFunction... no need to do anything.
    return f;
  } else {
    return JSFunction._create(f);
  }
}

/// Cached JSFunction associated with the Dart function when "this" is
/// captured.
Expando<JSFunction> _interopCaptureThisExpando = new Expando<JSFunction>();

/// Returns a [Function] that when called from JavaScript captures its 'this'
/// binding and calls [f] with the value of this passed as the first argument.
/// When called from Dart, [null] will be passed as the first argument.
///
/// See the documention for [allowInterop]. This method should only be used with
/// package:js Dart-JavaScript interop.
JSFunction allowInteropCaptureThis(Function f) {
  if (f is JSFunction) {
    // Behavior when the function is already a JS function is unspecified.
    throw new ArgumentError(
        "Function is already a JS function so cannot capture this.");
    return f;
  } else {
    var ret = _interopCaptureThisExpando[f];
    if (ret == null) {
      // TODO(jacobr): we could optimize this.
      ret = JSFunction._createWithThis(f);
      _interopCaptureThisExpando[f] = ret;
    }
    return ret;
  }
}
