// 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:html' show Blob, Event, ImageData, Node, Window;
import 'dart:collection' show HashMap, ListMixin;
import 'dart:indexed_db' show KeyRange;
import 'dart:typed_data' show TypedData;

import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS;
import 'dart:_interceptors' show JavaScriptObject, UnknownJavaScriptObject;
import 'dart:_js_helper' show Primitives, convertDartClosureToJS,
    getIsolateAffinityTag;

final JsObject context = _wrapToDart(Primitives.computeGlobalThis());

_convertDartFunction(Function f, {bool captureThis: false}) {
  return JS('',
    'function(_call, f, captureThis) {'
      'return function() {'
        'return _call(f, captureThis, this, '
            'Array.prototype.slice.apply(arguments));'
      '}'
    '}(#, #, #)', DART_CLOSURE_TO_JS(_callDartFunction), f, captureThis);
}

_callDartFunction(callback, bool captureThis, self, List arguments) {
  if (captureThis) {
    arguments = [self]..addAll(arguments);
  }
  var dartArgs = new List.from(arguments.map(_convertToDart));
  return _convertToJS(Function.apply(callback, dartArgs));
}

/**
 * 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 {
  // The wrapped JS object.
  final dynamic _jsObject;

  // This shoud only be called from _wrapToDart
  JsObject._fromJs(this._jsObject) {
    assert(_jsObject != null);
  }

  /**
   * Constructs a new JavaScript object from [constructor] and returns a proxy
   * to it.
   */
  factory JsObject(JsFunction constructor, [List arguments]) {
    var constr = _convertToJS(constructor);
    if (arguments == null) {
      return _wrapToDart(JS('', 'new #()', constr));
    }
    // The following code solves the problem of invoking a JavaScript
    // constructor with an unknown number arguments.
    // First bind the constructor to the argument list using bind.apply().
    // The first argument to bind() is the binding of 'this', so add 'null' to
    // the arguments list passed to apply().
    // After that, use the JavaScript 'new' operator which overrides any binding
    // of 'this' with the new instance.
    var args = [null]..addAll(arguments.map(_convertToJS));
    var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
    // Without this line, calling factoryFunction as a constructor throws
    JS('String', 'String(#)', factoryFunction);
    // This could return an UnknownJavaScriptObject, or a native
    // object for which there is an interceptor
    var jsObj = JS('JavaScriptObject', 'new #()', factoryFunction);

    return _wrapToDart(jsObj);
  }

  /**
   * 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");
    }
    return _wrapToDart(_convertToJS(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 _wrapToDart(_convertDataTree(object));
  }

  static _convertDataTree(data) {
    var _convertedObjects = new HashMap.identity();

    _convert(o) {
      if (_convertedObjects.containsKey(o)) {
        return _convertedObjects[o];
      }
      if (o is Map) {
        final convertedMap = JS('=Object', '{}');
        _convertedObjects[o] = convertedMap;
        for (var key in o.keys) {
          JS('=Object', '#[#]=#', convertedMap, key, _convert(o[key]));
        }
        return convertedMap;
      } else if (o is Iterable) {
        var convertedList = [];
        _convertedObjects[o] = convertedList;
        convertedList.addAll(o.map(_convert));
        return convertedList;
      } else {
        return _convertToJS(o);
      }
    }

    return _convert(data);
  }

  /**
   * Returns the value associated with [property] from the proxied JavaScript
   * object.
   *
   * The type of [property] must be either [String] or [num].
   */
  dynamic operator[](property) {
    if (property is! String && property is! num) {
      throw new ArgumentError("property is not a String or num");
    }
    return _convertToDart(JS('', '#[#]', _jsObject, property));
  }

  /**
   * Sets the value associated with [property] on the proxied JavaScript
   * object.
   *
   * The type of [property] must be either [String] or [num].
   */
  operator[]=(property, value) {
    if (property is! String && property is! num) {
      throw new ArgumentError("property is not a String or num");
    }
    JS('', '#[#]=#', _jsObject, property, _convertToJS(value));
  }

  int get hashCode => 0;

  bool operator==(other) => other is JsObject &&
      JS('bool', '# === #', _jsObject, other._jsObject);

  /**
   * 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(property) {
    if (property is! String && property is! num) {
      throw new ArgumentError("property is not a String or num");
    }
    return JS('bool', '# in #', property, _jsObject);
  }

  /**
   * Removes [property] from the JavaScript object.
   *
   * This is the equivalent of the `delete` operator in JavaScript.
   */
  void deleteProperty(property) {
    if (property is! String && property is! num) {
      throw new ArgumentError("property is not a String or num");
    }
    JS('bool', 'delete #[#]', _jsObject, property);
  }

  /**
   * 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) {
    return JS('bool', '# instanceof #', _jsObject, _convertToJS(type));
  }

  /**
   * Returns the result of the JavaScript objects `toString` method.
   */
  String toString() {
    try {
      return JS('String', 'String(#)', _jsObject);
    } catch(e) {
      return super.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].
   */
  dynamic callMethod(method, [List args]) {
    if (method is! String && method is! num) {
      throw new ArgumentError("method is not a String or num");
    }
    return _convertToDart(JS('', '#[#].apply(#, #)', _jsObject, method,
        _jsObject,
        args == null ? null : new List.from(args.map(_convertToJS))));
  }
}

/**
 * Proxies a JavaScript Function object.
 */
class JsFunction extends JsObject {

  /**
   * 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) {
    var jsFunc = _convertDartFunction(f, captureThis: true);
    return new JsFunction._fromJs(jsFunc);
  }

  JsFunction._fromJs(jsObject) : super._fromJs(jsObject);

  /**
   * 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 }) =>
      _convertToDart(JS('', '#.apply(#, #)', _jsObject,
          _convertToJS(thisArg),
          args == null ? null : new List.from(args.map(_convertToJS))));
}

/**
 * A [List] that proxies a JavaScript array.
 */
class JsArray<E> extends JsObject with ListMixin<E> {

  /**
   * Creates a new JavaScript array.
   */
  JsArray() : super._fromJs([]);

  /**
   * Creates a new JavaScript array and initializes it to the contents of
   * [other].
   */
  JsArray.from(Iterable<E> other)
      : super._fromJs([]..addAll(other.map(_convertToJS)));

  JsArray._fromJs(jsObject) : super._fromJs(jsObject);

  _checkIndex(int index) {
    if (index is int && (index < 0 || index >= length)) {
      throw new RangeError.range(index, 0, length);
    }
  }

  _checkInsertIndex(int index) {
    if (index is int && (index < 0 || index >= length + 1)) {
      throw new RangeError.range(index, 0, length);
    }
  }

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

  // Methods required by ListMixin

  E operator [](index) {
    // TODO(justinfagnani): fix the semantics for non-ints
    // dartbug.com/14605
    if (index is num && index == index.toInt()) {
      _checkIndex(index);
    }
    return super[index];
  }

  void operator []=(index, E value) {
    // TODO(justinfagnani): fix the semantics for non-ints
    // dartbug.com/14605
    if (index is num && index == index.toInt()) {
      _checkIndex(index);
    }
    super[index] = value;
  }

  int get length => super['length'];

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


  // Methods overriden for better performance

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

  void addAll(Iterable<E> iterable) {
    var list = (JS('bool', '# instanceof Array', iterable))
        ? iterable
        : new List.from(iterable);
    callMethod('push', list);
  }

  void insert(int index, E element) {
    _checkInsertIndex(index);
    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]);
  }
}

// property added to a Dart object referencing its JS-side DartObject proxy
final String _DART_OBJECT_PROPERTY_NAME =
    getIsolateAffinityTag(r'_$dart_dartObject');
final String _DART_CLOSURE_PROPERTY_NAME =
    getIsolateAffinityTag(r'_$dart_dartClosure');

// property added to a JS object referencing its Dart-side JsObject proxy
const _JS_OBJECT_PROPERTY_NAME = r'_$dart_jsObject';
const _JS_FUNCTION_PROPERTY_NAME = r'$dart_jsFunction';

bool _defineProperty(o, String name, value) {
  if (JS('bool', 'Object.isExtensible(#)', o)) {
    try {
      JS('void', 'Object.defineProperty(#, #, { value: #})', o, name, value);
      return true;
    } catch(e) {
      // object is native and lies about being extensible
      // see https://bugzilla.mozilla.org/show_bug.cgi?id=775185
    }
  }
  return false;
}

Object _getOwnProperty(o, String name) {
  if (JS('bool', 'Object.prototype.hasOwnProperty.call(#, #)', o, name)) {
    return JS('', '#[#]', o, name);
  }
  return null;
}

bool _isLocalObject(o) => JS('bool', '# instanceof Object', o);

// The shared constructor function for proxies to Dart objects in JavaScript.
final _dartProxyCtor = JS('', 'function DartObject(o) { this.o = o; }');

dynamic _convertToJS(dynamic o) {
  if (o == null) {
    return null;
  } else if (o is String || o is num || o is bool
      || o is Blob || o is Event || o is KeyRange || o is ImageData
      || o is Node || o is TypedData || o is Window) {
    return o;
  } else if (o is DateTime) {
    return Primitives.lazyAsJsDate(o);
  } else if (o is JsObject) {
    return o._jsObject;
  } else if (o is Function) {
    return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) {
      var jsFunction = _convertDartFunction(o);
      // set a property on the JS closure referencing the Dart closure
      _defineProperty(jsFunction, _DART_CLOSURE_PROPERTY_NAME, o);
      return jsFunction;
    });
  } else {
    var ctor = _dartProxyCtor;
    return _getJsProxy(o, _JS_OBJECT_PROPERTY_NAME,
        (o) => JS('', 'new #(#)', ctor, o));
  }
}

Object _getJsProxy(o, String propertyName, createProxy(o)) {
  var jsProxy = _getOwnProperty(o, propertyName);
  if (jsProxy == null) {
    jsProxy = createProxy(o);
    _defineProperty(o, propertyName, jsProxy);
  }
  return jsProxy;
}

// converts a Dart object to a reference to a native JS object
// which might be a DartObject JS->Dart proxy
Object _convertToDart(o) {
  if (JS('bool', '# == null', o) ||
      JS('bool', 'typeof # == "string"', o) ||
      JS('bool', 'typeof # == "number"', o) ||
      JS('bool', 'typeof # == "boolean"', o)) {
    return o;
  } else if (_isLocalObject(o)
      && (o is Blob || o is Event || o is KeyRange || o is ImageData
      || o is Node || o is TypedData || o is Window)) {
    // long line: dart2js doesn't allow string concatenation in the JS() form
    return JS('Blob|Event|KeyRange|ImageData|Node|TypedData|Window', '#', o);
  } else if (JS('bool', '# instanceof Date', o)) {
    var ms = JS('num', '#.getTime()', o);
    return new DateTime.fromMillisecondsSinceEpoch(ms);
  } else if (JS('bool', '#.constructor === #', o, _dartProxyCtor)) {
    return JS('', '#.o', o);
  } else {
    return _wrapToDart(o);
  }
}

JsObject _wrapToDart(o) {
  if (JS('bool', 'typeof # == "function"', o)) {
    return _getDartProxy(o, _DART_CLOSURE_PROPERTY_NAME,
        (o) => new JsFunction._fromJs(o));
  } else if (JS('bool', '# instanceof Array', o)) {
    return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
        (o) => new JsArray._fromJs(o));
  } else {
    return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
        (o) => new JsObject._fromJs(o));
  }
}

Object _getDartProxy(o, String propertyName, createProxy(o)) {
  var dartProxy = _getOwnProperty(o, propertyName);
  // Temporary fix for dartbug.com/15193
  // In some cases it's possible to see a JavaScript object that
  // came from a different context and was previously proxied to
  // Dart in that context. The JS object will have a cached proxy
  // but it won't be a valid Dart object in this context.
  // For now we throw away the cached proxy, but we should be able
  // to cache proxies from multiple JS contexts and Dart isolates.
  if (dartProxy == null || !_isLocalObject(o)) {
    dartProxy = createProxy(o);
    _defineProperty(o, propertyName, dartProxy);
  }
  return dartProxy;
}
