part of html_common;

convertDartToNative_PrepareForStructuredClone(value) =>
    new _StructuredCloneDartium().convertDartToNative_PrepareForStructuredClone(value);

convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) =>
    new _AcceptStructuredCloneDartium().convertNativeToDart_AcceptStructuredClone(object, mustCopy: mustCopy);

class _StructuredCloneDartium extends _StructuredClone {
  newJsMap() => js.JsNative.newObject();
  putIntoMap(map, key, value) => js.JsNative.setProperty(map, key, value);
  newJsList(length) => js.JsNative.newArray()..length = length;
  cloneNotRequired(e) =>
      e is js.JSObject || e is TypedData || e is ByteBuffer;
}

/// A version of _AcceptStructuredClone, but using a different algorithm
/// so we can take advantage of an identity HashMap on Dartium without
/// the bad side-effect of modifying the JS source objects if we do the same in
/// dart2js.
///
/// This no longer inherits anything from _AcceptStructuredClone
/// and is never used polymorphically with it, so it doesn't inherit.
class _AcceptStructuredCloneDartium {
  newDartList(length) => new List(length);

  // As long as we stick to JSObject instead of intermingling legacy JsObject,
  // we can simply use identical.
  bool identicalInJs(a, b) => identical(a, b);

  void forEachJsField(jsObject, action) {
    var keys = js.JsNative.callMethod(_object, "keys", [jsObject]);
    for (var key in keys) {
      action(key, js.JsNative.getProperty(jsObject, key));
    }
  }

  // Keep track of the clones, keyed by the original object. If we're
  // not copying, these may be the same.
  var clones = new HashMap.identity();
  bool mustCopy = false;

  Object findSlot(value) {
    return clones.putIfAbsent(value, () => null);
  }

  writeSlot(original, x) { clones[original] = x; }

  walk(e) {
    if (e == null) return e;
    if (e is bool) return e;
    if (e is num) return e;
    if (e is String) return e;
    if (e is DateTime) return e;

    if (isJavaScriptRegExp(e)) {
      // TODO(sra).
      throw new UnimplementedError('structured clone of RegExp');
    }

    if (isJavaScriptPromise(e)) {
      return convertNativePromiseToDartFuture(e);
    }

    if (isJavaScriptSimpleObject(e)) {
      // TODO(sra): If mustCopy is false, swizzle the prototype for one of a Map
      // implementation that uses the properies as storage.
      var copy = findSlot(e);
      if (copy != null) return copy;
      copy = {};

      writeSlot(e, copy);
      forEachJsField(e, (key, value) => copy[key] = walk(value));
      return copy;
    }

    if (isJavaScriptArray(e)) {
      var copy = findSlot(e);
      if (copy != null) return copy;

      int length = e.length;
      // Since a JavaScript Array is an instance of Dart List, we can modify it
      // in-place unless we must copy.
      copy = mustCopy ? newDartList(length) : e;
      writeSlot(e, copy);

      for (int i = 0; i < length; i++) {
        copy[i] = walk(e[i]);
      }
      return copy;
    }

    // Assume anything else is already a valid Dart object, either by having
    // already been processed, or e.g. a clonable native class.
    return e;
  }

  convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) {
    this.mustCopy = mustCopy;
    var copy = walk(object);
    return copy;
  }
}

final _dateConstructor = js.JsNative.getProperty(window, "Date");
final _regexConstructor = js.JsNative.getProperty(window, "RegExp");

bool isJavaScriptDate(value) => value is js.JSObject && js.JsNative.instanceof(value, _dateConstructor);
bool isJavaScriptRegExp(value) => value is js.JSObject && js.JsNative.instanceof(value, _regexConstructor);
bool isJavaScriptArray(value) => value is js.JSArray;

final _object = js.JsNative.getProperty(window, "Object");
final _getPrototypeOf = js.JsNative.getProperty(_object, "getPrototypeOf");
_getProto(object) {
  return _getPrototypeOf(object);
}
final _objectProto = js.JsNative.getProperty(_object, "prototype");

bool isJavaScriptSimpleObject(value) {
  if (value is! js.JSObject) return false;
  var proto = _getProto(value);
  return proto == _objectProto || proto == null;
}

// TODO(jacobr): this makes little sense unless we are doing something
// ambitious to make Dartium and Dart2Js interop well with each other.
bool isImmutableJavaScriptArray(value) =>
    isJavaScriptArray(value) && js.JsNative.getProperty(value, "immutable$list") != null;

final _promiseConstructor = js.JsNative.getProperty(window, 'Promise');
bool isJavaScriptPromise(value) => value is js.JSObject && identical(js.JsNative.getProperty(value, 'constructor'), _promiseConstructor);

Future convertNativePromiseToDartFuture(js.JSObject promise) {
  var completer = new Completer();
  var newPromise = js.JsNative.callMethod(js.JsNative.callMethod(promise,
    "then", [js.allowInterop((result) => completer.complete(result))]),
    "catch", [js.allowInterop((result) => completer.completeError(result))]);
  return completer.future;
}

convertDartToNative_DateTime(DateTime date) {
  return date;
}

/// Creates a Dart Rectangle from a Javascript object with properties
/// left, top, width and height or a 4 element array of integers. Used internally in Dartium.
Rectangle make_dart_rectangle(r) {
  if (r == null) return null;
  if (r is List) {
    return new Rectangle(r[0], r[1], r[2], r[3]);
  }

  return new Rectangle(
      js.JsNative.getProperty(r, 'left'),
      js.JsNative.getProperty(r, 'top'),
      js.JsNative.getProperty(r, 'width'),
      js.JsNative.getProperty(r, 'height'));
}

// Converts a flat Dart map into a JavaScript object with properties this is
// is the Dartium only version it uses dart:js.
// TODO(alanknight): This could probably be unified with the dart2js conversions
// code in html_common and be more general.
convertDartToNative_Dictionary(Map dict) {
  if (dict == null) return null;
  var jsObject = js.JsNative.newObject();
  dict.forEach((String key, value) {
    if (value is List) {
      var jsArray = js.JsNative.newArray();
      value.forEach((elem) {
        jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem);
      });
      js.JsNative.setProperty(jsObject, key, jsArray);
    } else {
      js.JsNative.setProperty(jsObject, key, value);
    }
  });
  return jsObject;
}

// Creates a Dart class to allow members of the Map to be fetched (as if getters exist).
// TODO(terry): Need to use package:js but that's a problem in dart:html. Talk to
//              Jacob about how to do this properly using dart:js.
class _ReturnedDictionary {
  Map _values;

  noSuchMethod(Invocation invocation) {
    var key = MirrorSystem.getName(invocation.memberName);
    if (invocation.isGetter) {
      return _values[key];
    } else if (invocation.isSetter && key.endsWith('=')) {
      key = key.substring(0, key.length-1);
      _values[key] = invocation.positionalArguments[0];
    }
  }

  Map get toMap => _values;

  _ReturnedDictionary(Map value): _values = value != null ? value : {};
}

// Helper function to wrapped a returned dictionary from blink to a Dart looking
// class.
convertNativeDictionaryToDartDictionary(values) {
  if (values is! Map) {
    // TODO(jacobr): wish wwe didn't have to do this.
    values = convertNativeToDart_SerializedScriptValue(values);
  }
  return values != null ? new _ReturnedDictionary(values) : null;
}

convertNativeToDart_Dictionary(values) => convertNativeToDart_SerializedScriptValue(values);

// Conversion function place holder (currently not used in dart2js or dartium).
List convertDartToNative_StringArray(List<String> input) => input;

// Converts a Dart list into a JsArray. For the Dartium version only.
convertDartToNative_List(List input) => new js.JsArray()..addAll(input);

// Incredibly slow implementation to lookup the runtime type for an object.
// Fortunately, performance doesn't matter much as the results are cached
// as long as the object being looked up has a valid prototype.
// TODO(jacobr): we should track the # of lookups to ensure that things aren't
// going off the rails due to objects with null prototypes, etc.
// Note: unlike all other methods in this class, here we intentionally use
// the old JsObject types to bootstrap the new typed bindings.
Type lookupType(js.JsObject jsObject, bool isElement) {
  try {
  // TODO(jacobr): add static methods that return the runtime type of the patch
  // class so that this code works as expected.
  if (jsObject is js.JsArray) {
    return js.JSArray.instanceRuntimeType;
  }
  if (jsObject is js.JsFunction) {
    return js.JSFunction.instanceRuntimeType;
  }

    var constructor = js.JsNative.getProperty(jsObject, 'constructor');
    if (constructor == null) {
      // Perfectly valid case for JavaScript objects where __proto__ has
      // intentionally been set to null.
      // We should track and warn about this case as peformance will be poor.
      return js.JSObject.instanceRuntimeType;
    }
    var jsTypeName = js.JsNative.getProperty(constructor, 'name');
    if (jsTypeName is! String || jsTypeName.length == 0) {
      // Not an html type.
      return js.JSObject.instanceRuntimeType;
    }

    var dartClass_instance;
    var customElementClass = null;
    var extendsTag = "";    

    Type type = getHtmlCreateType(jsTypeName);
    if (type != null) return type;

    // Start walking the prototype chain looking for a JS class.
    var prototype = js.JsNative.getProperty(jsObject, '__proto__');
    while (prototype != null) {
      // We're a Dart class that's pointing to a JS class.
      var constructor = js.JsNative.getProperty(prototype, 'constructor');
      if (constructor != null) {          
        jsTypeName = js.JsNative.getProperty(constructor, 'name');
        type = getHtmlCreateType(jsTypeName);
        if (type != null) return type;
      }
      prototype = js.JsNative.getProperty(prototype, '__proto__');
    }
  } catch (e, stacktrace) {
    if (e is DebugAssertException) print("${e.message}\n ${stacktrace}");
    else print("${stacktrace}");
  }
  return js.JSObject.instanceRuntimeType;
}
