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

part of _js_helper;

// TODO(ngeoffray): stop using this method once our optimizers can
// change str1.contains(str2) into str1.indexOf(str2) != -1.
bool contains(String userAgent, String name) {
  return JS('int', '#.indexOf(#)', userAgent, name) != -1;
}

int arrayLength(List array) {
  return JS('int', '#.length', array);
}

arrayGet(List array, int index) {
  return JS('var', '#[#]', array, index);
}

void arraySet(List array, int index, var value) {
  JS('var', '#[#] = #', array, index, value);
}

propertyGet(var object, String property) {
  return JS('var', '#[#]', object, property);
}

bool callHasOwnProperty(var function, var object, String property) {
  return JS('bool', '#.call(#, #)', function, object, property);
}

void propertySet(var object, String property, var value) {
  JS('var', '#[#] = #', object, property, value);
}

getPropertyFromPrototype(var object, String name) {
  return JS('var', 'Object.getPrototypeOf(#)[#]', object, name);
}

/**
 * Returns a String tag identifying the type of the native object, or `null`.
 * The tag is not the name of the type, but usually the name of the JavaScript
 * constructor function.  Initialized by [initHooks].
 */
Function getTagFunction;

/**
 * If a lookup via [getTagFunction] on an object [object] that has [tag] fails,
 * this function is called to provide an alternate tag.  This allows us to fail
 * gracefully if we can make a good guess, for example, when browsers add novel
 * kinds of HTMLElement that we have never heard of.  Initialized by
 * [initHooks].
 */
Function alternateTagFunction;

/**
 * Returns the prototype for the JavaScript constructor named by an input tag.
 * Returns `null` if there is no such constructor, or if pre-patching of the
 * constructor is to be avoided.  Initialized by [initHooks].
 */
Function prototypeForTagFunction;

String toStringForNativeObject(var obj) {
  // TODO(sra): Is this code dead?
  // [getTagFunction] might be uninitialized, but in usual usage, toString has
  // been called via an interceptor and initialized it.
  String name = getTagFunction == null
      ? '<Unknown>'
      : JS('String', '#', getTagFunction(obj));
  return 'Instance of $name';
}

int hashCodeForNativeObject(object) => Primitives.objectHashCode(object);

/**
 * Sets a JavaScript property on an object.
 */
void defineProperty(var obj, String property, var value) {
  JS(
      'void',
      'Object.defineProperty(#, #, '
      '{value: #, enumerable: false, writable: true, configurable: true})',
      obj,
      property,
      value);
}

// Is [obj] an instance of a Dart-defined class?
bool isDartObject(obj) {
  // Some of the extra parens here are necessary.
  return JS(
      'bool',
      '((#) instanceof (#))',
      obj,
      JS_BUILTIN(
          'depends:none;effects:none;', JsBuiltin.dartObjectConstructor));
}

/**
 * A JavaScript object mapping tags to the constructors of interceptors.
 * This is a JavaScript object with no prototype.
 *
 * Example: 'HTMLImageElement' maps to the ImageElement class constructor.
 */
get interceptorsByTag => JS_EMBEDDED_GLOBAL('=Object', INTERCEPTORS_BY_TAG);

/**
 * A JavaScript object mapping tags to `true` or `false`.
 *
 * Example: 'HTMLImageElement' maps to `true` since, as there are no subclasses
 * of ImageElement, it is a leaf class in the native class hierarchy.
 */
get leafTags => JS_EMBEDDED_GLOBAL('=Object', LEAF_TAGS);

String findDispatchTagForInterceptorClass(interceptorClassConstructor) {
  return JS(
      '', r'#.#', interceptorClassConstructor, NATIVE_SUPERCLASS_TAG_NAME);
}

/**
 * Cache of dispatch records for instances.  This is a JavaScript object used as
 * a map.  Keys are instance tags, e.g. "!SomeThing".  The cache permits the
 * sharing of one dispatch record between multiple instances.
 */
var dispatchRecordsForInstanceTags;

/**
 * Cache of interceptors indexed by uncacheable tags, e.g. "~SomeThing".
 * This is a JavaScript object used as a map.
 */
var interceptorsForUncacheableTags;

lookupInterceptor(String tag) {
  return propertyGet(interceptorsByTag, tag);
}

// Dispatch tag marks are optional prefixes for a dispatch tag that direct how
// the interceptor for the tag may be cached.

/// No caching permitted.
const UNCACHED_MARK = '~';

/// Dispatch record must be cached per instance
const INSTANCE_CACHED_MARK = '!';

/// Dispatch record is cached on immediate prototype.
const LEAF_MARK = '-';

/// Dispatch record is cached on immediate prototype with a prototype
/// verification to prevent the interceptor being associated with a subclass
/// before a dispatch record is cached on the subclass.
const INTERIOR_MARK = '+';

/// A 'discriminator' function is to be used. TBD.
const DISCRIMINATED_MARK = '*';

/**
 * Returns the interceptor for a native object, or returns `null` if not found.
 *
 * A dispatch record is cached according to the specification of the dispatch
 * tag for [obj].
 */
@NoInline()
lookupAndCacheInterceptor(obj) {
  assert(!isDartObject(obj));
  String tag = getTagFunction(obj);

  // Fast path for instance (and uncached) tags because the lookup is repeated
  // for each instance (or getInterceptor call).
  var record = propertyGet(dispatchRecordsForInstanceTags, tag);
  if (record != null) return patchInstance(obj, record);
  var interceptor = propertyGet(interceptorsForUncacheableTags, tag);
  if (interceptor != null) return interceptor;

  // This lookup works for derived dispatch tags because we add them all in
  // [initNativeDispatch].
  var interceptorClass = lookupInterceptor(tag);
  if (interceptorClass == null) {
    tag = alternateTagFunction(obj, tag);
    if (tag != null) {
      // Fast path for instance and uncached tags again.
      record = propertyGet(dispatchRecordsForInstanceTags, tag);
      if (record != null) return patchInstance(obj, record);
      interceptor = propertyGet(interceptorsForUncacheableTags, tag);
      if (interceptor != null) return interceptor;

      interceptorClass = lookupInterceptor(tag);
    }
  }

  if (interceptorClass == null) {
    // This object is not known to Dart.  There could be several reasons for
    // that, including (but not limited to):
    //
    // * A bug in native code (hopefully this is caught during development).
    // * An unknown DOM object encountered.
    // * JavaScript code running in an unexpected context.  For example, on
    //   node.js.
    return null;
  }

  interceptor = JS('', '#.prototype', interceptorClass);

  var mark = JS('String|Null', '#[0]', tag);

  if (mark == INSTANCE_CACHED_MARK) {
    record = makeLeafDispatchRecord(interceptor);
    propertySet(dispatchRecordsForInstanceTags, tag, record);
    return patchInstance(obj, record);
  }

  if (mark == UNCACHED_MARK) {
    propertySet(interceptorsForUncacheableTags, tag, interceptor);
    return interceptor;
  }

  if (mark == LEAF_MARK) {
    return patchProto(obj, makeLeafDispatchRecord(interceptor));
  }

  if (mark == INTERIOR_MARK) {
    return patchInteriorProto(obj, interceptor);
  }

  if (mark == DISCRIMINATED_MARK) {
    // TODO(sra): Use discriminator of tag.
    throw new UnimplementedError(tag);
  }

  // [tag] was not explicitly an interior or leaf tag, so
  var isLeaf = JS('bool', '(#[#]) === true', leafTags, tag);
  if (isLeaf) {
    return patchProto(obj, makeLeafDispatchRecord(interceptor));
  } else {
    return patchInteriorProto(obj, interceptor);
  }
}

patchInstance(obj, record) {
  setDispatchProperty(obj, record);
  return dispatchRecordInterceptor(record);
}

patchProto(obj, record) {
  setDispatchProperty(JS('', 'Object.getPrototypeOf(#)', obj), record);
  return dispatchRecordInterceptor(record);
}

patchInteriorProto(obj, interceptor) {
  var proto = JS('', 'Object.getPrototypeOf(#)', obj);
  var record = makeDispatchRecord(interceptor, proto, null, null);
  setDispatchProperty(proto, record);
  return interceptor;
}

makeLeafDispatchRecord(interceptor) {
  var fieldName = JS_GET_NAME(JsGetName.IS_INDEXABLE_FIELD_NAME);
  bool indexability = JS('bool', r'!!#[#]', interceptor, fieldName);
  return makeDispatchRecord(interceptor, false, null, indexability);
}

makeDefaultDispatchRecord(tag, interceptorClass, proto) {
  var interceptor = JS('', '#.prototype', interceptorClass);
  var isLeaf = JS('bool', '(#[#]) === true', leafTags, tag);
  if (isLeaf) {
    return makeLeafDispatchRecord(interceptor);
  } else {
    return makeDispatchRecord(interceptor, proto, null, null);
  }
}

/**
 * [proto] should have no shadowing prototypes that are not also assigned a
 * dispatch rescord.
 */
setNativeSubclassDispatchRecord(proto, interceptor) {
  setDispatchProperty(proto, makeLeafDispatchRecord(interceptor));
}

String constructorNameFallback(object) {
  return JS('String', '#(#)', _constructorNameFallback, object);
}

var initNativeDispatchFlag; // null or true

@NoInline()
void initNativeDispatch() {
  if (true == initNativeDispatchFlag) return;
  initNativeDispatchFlag = true;
  initNativeDispatchContinue();
}

@NoInline()
void initNativeDispatchContinue() {
  dispatchRecordsForInstanceTags = JS('', 'Object.create(null)');
  interceptorsForUncacheableTags = JS('', 'Object.create(null)');

  initHooks();

  // Try to pro-actively patch prototypes of DOM objects.  For each of our known
  // tags `TAG`, if `window.TAG` is a (constructor) function, set the dispatch
  // property if the function's prototype to a dispatch record.
  var map = interceptorsByTag;
  var tags = JS('JSMutableArray', 'Object.getOwnPropertyNames(#)', map);

  if (JS('bool', 'typeof window != "undefined"')) {
    var context = JS('=Object', 'window');
    var fun = JS('=Object', 'function () {}');
    for (int i = 0; i < tags.length; i++) {
      var tag = tags[i];
      var proto = prototypeForTagFunction(tag);
      if (proto != null) {
        var interceptorClass = JS('', '#[#]', map, tag);
        var record = makeDefaultDispatchRecord(tag, interceptorClass, proto);
        if (record != null) {
          setDispatchProperty(proto, record);
          // Ensure the modified prototype is still fast by assigning it to
          // the prototype property of a function object.
          JS('', '#.prototype = #', fun, proto);
        }
      }
    }
  }

  // [interceptorsByTag] maps 'plain' dispatch tags.  Add all the derived
  // dispatch tags to simplify lookup of derived tags.
  for (int i = 0; i < tags.length; i++) {
    var tag = JS('String', '#[#]', tags, i);
    if (JS('bool', '/^[A-Za-z_]/.test(#)', tag)) {
      var interceptorClass = propertyGet(map, tag);
      propertySet(map, INSTANCE_CACHED_MARK + tag, interceptorClass);
      propertySet(map, UNCACHED_MARK + tag, interceptorClass);
      propertySet(map, LEAF_MARK + tag, interceptorClass);
      propertySet(map, INTERIOR_MARK + tag, interceptorClass);
      propertySet(map, DISCRIMINATED_MARK + tag, interceptorClass);
    }
  }
}

/**
 * Initializes [getTagFunction] and [alternateTagFunction].
 *
 * These functions are 'hook functions', collectively 'hooks'.  They initialized
 * by applying a series of hooks transformers.  Built-in hooks transformers deal
 * with various known browser behaviours.
 *
 * Each hook tranformer takes a 'hooks' input which is a JavaScript object
 * containing the hook functions, and returns the same or a new object with
 * replacements.  The replacements can wrap the originals to provide alternate
 * or modified behaviour.
 *
 *     { getTag: function(obj) {...},
 *       getUnknownTag: function(obj, tag) {...},
 *       prototypeForTag: function(tag) {...},
 *       discriminator: function(tag) {...},
 *      }
 *
 * * getTag(obj) returns the dispatch tag, or `null`.
 * * getUnknownTag(obj, tag) returns a tag when [getTag] fails.
 * * prototypeForTag(tag) returns the prototype of the constructor for tag,
 *   or `null` if not available or prepatching is undesirable.
 * * discriminator(tag) returns a function TBD.
 *
 * The web site can adapt a dart2js application by loading code ahead of the
 * dart2js application that defines hook transformers to be after the built in
 * ones.  Code defining a transformer HT should use the following pattern to
 * ensure multiple transformers can be composed:
 *
 *     (dartNativeDispatchHooksTransformer =
 *      window.dartNativeDispatchHooksTransformer || []).push(HT);
 *
 *
 * TODO: Implement and describe dispatch tags and their caching methods.
 */
void initHooks() {
  // The initial simple hooks:
  var hooks = JS('', '#()', _baseHooks);

  // Customize for browsers where `object.constructor.name` fails:
  var _fallbackConstructorHooksTransformer = JS('', '#(#)',
      _fallbackConstructorHooksTransformerGenerator, _constructorNameFallback);
  hooks = applyHooksTransformer(_fallbackConstructorHooksTransformer, hooks);

  // Customize for browsers:
  hooks = applyHooksTransformer(_firefoxHooksTransformer, hooks);
  hooks = applyHooksTransformer(_ieHooksTransformer, hooks);
  hooks = applyHooksTransformer(_operaHooksTransformer, hooks);
  hooks = applyHooksTransformer(_safariHooksTransformer, hooks);

  hooks = applyHooksTransformer(_fixDocumentHooksTransformer, hooks);

  // TODO(sra): Update ShadowDOM polyfil to use
  // [dartNativeDispatchHooksTransformer] and remove this hook.
  hooks = applyHooksTransformer(
      _dartExperimentalFixupGetTagHooksTransformer, hooks);

  // Apply global hooks.
  //
  // If defined, dartNativeDispatchHookdTransformer should be a single function
  // of a JavaScript Array of functions.

  if (JS('bool', 'typeof dartNativeDispatchHooksTransformer != "undefined"')) {
    var transformers = JS('', 'dartNativeDispatchHooksTransformer');
    if (JS('bool', 'typeof # == "function"', transformers)) {
      transformers = [transformers];
    }
    if (JS('bool', '#.constructor == Array', transformers)) {
      for (int i = 0; i < JS('int', '#.length', transformers); i++) {
        var transformer = JS('', '#[#]', transformers, i);
        if (JS('bool', 'typeof # == "function"', transformer)) {
          hooks = applyHooksTransformer(transformer, hooks);
        }
      }
    }
  }

  var getTag = JS('', '#.getTag', hooks);
  var getUnknownTag = JS('', '#.getUnknownTag', hooks);
  var prototypeForTag = JS('', '#.prototypeForTag', hooks);

  getTagFunction = (o) => JS('String|Null', '#(#)', getTag, o);
  alternateTagFunction =
      (o, String tag) => JS('String|Null', '#(#, #)', getUnknownTag, o, tag);
  prototypeForTagFunction =
      (String tag) => JS('', '#(#)', prototypeForTag, tag);
}

applyHooksTransformer(transformer, hooks) {
  var newHooks = JS('=Object|Null', '#(#)', transformer, hooks);
  return JS('', '# || #', newHooks, hooks);
}

// JavaScript code fragments.
//
// This is a temporary place for the JavaScript code.
//
// TODO(sra): These code fragments are not minified.  They could be generated by
// the code emitter, or JS_CONST could be improved to parse entire functions and
// take care of the minification.

const _baseHooks = const JS_CONST(r'''
function() {
  var toStringFunction = Object.prototype.toString;
  function getTag(o) {
    var s = toStringFunction.call(o);
    return s.substring(8, s.length - 1);
  }
  function getUnknownTag(object, tag) {
    // This code really belongs in [getUnknownTagGenericBrowser] but having it
    // here allows [getUnknownTag] to be tested on d8.
    if (/^HTML[A-Z].*Element$/.test(tag)) {
      // Check that it is not a simple JavaScript object.
      var name = toStringFunction.call(object);
      if (name == "[object Object]") return null;
      return "HTMLElement";
    }
  }
  function getUnknownTagGenericBrowser(object, tag) {
    if (self.HTMLElement && object instanceof HTMLElement) return "HTMLElement";
    return getUnknownTag(object, tag);
  }
  function prototypeForTag(tag) {
    if (typeof window == "undefined") return null;
    if (typeof window[tag] == "undefined") return null;
    var constructor = window[tag];
    if (typeof constructor != "function") return null;
    return constructor.prototype;
  }
  function discriminator(tag) { return null; }

  var isBrowser = typeof navigator == "object";

  return {
    getTag: getTag,
    getUnknownTag: isBrowser ? getUnknownTagGenericBrowser : getUnknownTag,
    prototypeForTag: prototypeForTag,
    discriminator: discriminator };
}''');

/**
 * Returns the name of the constructor function for browsers where
 * `object.constructor.name` is not reliable.
 *
 * This function is split out of [_fallbackConstructorHooksTransformerGenerator]
 * as it is called from both the dispatch hooks and via
 * [constructorNameFallback] from objectToString.
 */
const _constructorNameFallback = const JS_CONST(r'''
function getTagFallback(o) {
  var s = Object.prototype.toString.call(o);
  return s.substring(8, s.length - 1);
}''');

const _fallbackConstructorHooksTransformerGenerator = const JS_CONST(r'''
function(getTagFallback) {
  return function(hooks) {
    // If we are not in a browser, assume we are in d8.
    // TODO(sra): Recognize jsshell.
    if (typeof navigator != "object") return hooks;

    var ua = navigator.userAgent;
    // TODO(antonm): remove a reference to DumpRenderTree.
    if (ua.indexOf("DumpRenderTree") >= 0) return hooks;
    if (ua.indexOf("Chrome") >= 0) {
      // Confirm constructor name is usable for dispatch.
      function confirm(p) {
        return typeof window == "object" && window[p] && window[p].name == p;
      }
      if (confirm("Window") && confirm("HTMLElement")) return hooks;
    }

    hooks.getTag = getTagFallback;
  };
}''');

const _ieHooksTransformer = const JS_CONST(r'''
function(hooks) {
  var userAgent = typeof navigator == "object" ? navigator.userAgent : "";
  if (userAgent.indexOf("Trident/") == -1) return hooks;

  var getTag = hooks.getTag;

  var quickMap = {
    "BeforeUnloadEvent": "Event",
    "DataTransfer": "Clipboard",
    "HTMLDDElement": "HTMLElement",
    "HTMLDTElement": "HTMLElement",
    "HTMLPhraseElement": "HTMLElement",
    "Position": "Geoposition"
  };

  function getTagIE(o) {
    var tag = getTag(o);
    var newTag = quickMap[tag];
    if (newTag) return newTag;
    // Patches for types which report themselves as Objects.
    if (tag == "Object") {
      if (window.DataView && (o instanceof window.DataView)) return "DataView";
    }
    return tag;
  }

  function prototypeForTagIE(tag) {
    var constructor = window[tag];
    if (constructor == null) return null;
    return constructor.prototype;
  }

  hooks.getTag = getTagIE;
  hooks.prototypeForTag = prototypeForTagIE;
}''');

const _fixDocumentHooksTransformer = const JS_CONST(r'''
function(hooks) {
  var getTag = hooks.getTag;
  var prototypeForTag = hooks.prototypeForTag;
  function getTagFixed(o) {
    var tag = getTag(o);
    if (tag == "Document") {
      // Some browsers and the polymer polyfill call both HTML and XML documents
      // "Document", so we check for the xmlVersion property, which is the empty
      // string on HTML documents. Since both dart:html classes Document and
      // HtmlDocument share the same type, we must patch the instances and not
      // the prototype.
      if (!!o.xmlVersion) return "!Document";
      return "!HTMLDocument";
    }
    return tag;
  }

  function prototypeForTagFixed(tag) {
    if (tag == "Document") return null;  // Do not pre-patch Document.
    return prototypeForTag(tag);
  }

  hooks.getTag = getTagFixed;
  hooks.prototypeForTag = prototypeForTagFixed;
}''');

const _firefoxHooksTransformer = const JS_CONST(r'''
function(hooks) {
  var userAgent = typeof navigator == "object" ? navigator.userAgent : "";
  if (userAgent.indexOf("Firefox") == -1) return hooks;

  var getTag = hooks.getTag;

  var quickMap = {
    "BeforeUnloadEvent": "Event",
    "DataTransfer": "Clipboard",
    "GeoGeolocation": "Geolocation",
    "Location": "!Location",               // Fixes issue 18151
    "WorkerMessageEvent": "MessageEvent",
    "XMLDocument": "!Document"};

  function getTagFirefox(o) {
    var tag = getTag(o);
    return quickMap[tag] || tag;
  }

  hooks.getTag = getTagFirefox;
}''');

const _operaHooksTransformer = const JS_CONST(r'''
function(hooks) { return hooks; }
''');

const _safariHooksTransformer = const JS_CONST(r'''
function(hooks) { return hooks; }
''');

const _dartExperimentalFixupGetTagHooksTransformer = const JS_CONST(r'''
function(hooks) {
  if (typeof dartExperimentalFixupGetTag != "function") return hooks;
  hooks.getTag = dartExperimentalFixupGetTag(hooks.getTag);
}''');
