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

// Conversions for IDBKey.
//
// Per http://www.w3.org/TR/IndexedDB/#key-construct
//
// "A value is said to be a valid key if it is one of the following types: Array
// JavaScript objects [ECMA-262], DOMString [WEBIDL], Date [ECMA-262] or float
// [WEBIDL]. However Arrays are only valid keys if every item in the array is
// defined and is a valid key (i.e. sparse arrays can not be valid keys) and if
// the Array doesn't directly or indirectly contain itself. Any non-numeric
// properties are ignored, and thus does not affect whether the Array is a valid
// key. Additionally, if the value is of type float, it is only a valid key if
// it is not NaN, and if the value is of type Date it is only a valid key if its
// [[PrimitiveValue]] internal property, as defined by [ECMA-262], is not NaN."

// What is required is to ensure that an Lists in the key are actually
// JavaScript arrays, and any Dates are JavaScript Dates.

// Conversions for Window.  These check if the window is the local
// window, and if it's not, wraps or unwraps it with a secure wrapper.
// We need to test for EventTarget here as well as it's a base type.
// We omit an unwrapper for Window as no methods take a non-local
// window as a parameter.

part of html_common;

/// Converts a Dart value into a JavaScript SerializedScriptValue.
convertDartToNative_SerializedScriptValue(value) {
  return convertDartToNative_PrepareForStructuredClone(value);
}

/// Since the source object may be viewed via a JavaScript event listener the
/// original may not be modified.
convertNativeToDart_SerializedScriptValue(object) {
  return convertNativeToDart_AcceptStructuredClone(object, mustCopy: true);
}

/**
 * Converts a Dart value into a JavaScript SerializedScriptValue.  Returns the
 * original input or a functional 'copy'.  Does not mutate the original.
 *
 * The main transformation is the translation of Dart Maps are converted to
 * JavaScript Objects.
 *
 * The algorithm is essentially a dry-run of the structured clone algorithm
 * described at
 * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#structured-clone
 * https://www.khronos.org/registry/typedarray/specs/latest/#9
 *
 * Since the result of this function is expected to be passed only to JavaScript
 * operations that perform the structured clone algorithm which does not mutate
 * its output, the result may share structure with the input [value].
 */
abstract class _StructuredClone {
  // TODO(sra): Replace slots with identity hash table.
  var values = [];
  var copies = []; // initially 'null', 'true' during initial DFS, then a copy.

  int findSlot(value) {
    int length = values.length;
    for (int i = 0; i < length; i++) {
      if (identical(values[i], value)) return i;
    }
    values.add(value);
    copies.add(null);
    return length;
  }

  readSlot(int i) => copies[i];
  writeSlot(int i, x) {
    copies[i] = x;
  }

  cleanupSlots() {} // Will be needed if we mark objects with a property.
  bool cloneNotRequired(object);
  newJsMap();
  List newJsList(length);
  void putIntoMap(map, key, value);

  // Returns the input, or a clone of the input.
  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 convertDartToNative_DateTime(e);
    }
    if (e is RegExp) {
      // TODO(sra).
      throw new UnimplementedError('structured clone of RegExp');
    }

    // The browser's internal structured cloning algorithm will copy certain
    // types of object, but it will copy only its own implementations and not
    // just any Dart implementations of the interface.

    // TODO(sra): The JavaScript objects suitable for direct cloning by the
    // structured clone algorithm could be tagged with an private interface.

    if (e is File) return e;
    if (e is Blob) return e;
    if (e is FileList) return e;

    // TODO(sra): Firefox: How to convert _TypedImageData on the other end?
    if (e is ImageData) return e;
    if (cloneNotRequired(e)) return e;

    if (e is Map) {
      var slot = findSlot(e);
      var copy = readSlot(slot);
      if (copy != null) return copy;
      copy = newJsMap();
      writeSlot(slot, copy);
      e.forEach((key, value) {
        putIntoMap(copy, key, walk(value));
      });
      return copy;
    }

    if (e is List) {
      // Since a JavaScript Array is an instance of Dart List it is tempting
      // in dart2js to avoid making a copy of the list if there is no need
      // to copy anything reachable from the array.  However, the list may have
      // non-native properties or methods from interceptors and such, e.g.
      // an immutability marker. So we  had to stop doing that.
      var slot = findSlot(e);
      var copy = JS('List', '#', readSlot(slot));
      if (copy != null) return copy;
      copy = copyList(e, slot);
      return copy;
    }

    throw new UnimplementedError('structured clone of other type');
  }

  List copyList(List e, int slot) {
    int i = 0;
    int length = e.length;
    var copy = newJsList(length);
    writeSlot(slot, copy);
    for (; i < length; i++) {
      copy[i] = walk(e[i]);
    }
    return copy;
  }

  convertDartToNative_PrepareForStructuredClone(value) {
    var copy = walk(value);
    cleanupSlots();
    return copy;
  }
}

/**
 * Converts a native value into a Dart object.
 *
 * If [mustCopy] is [:false:], may return the original input.  May mutate the
 * original input (but will be idempotent if mutation occurs).  It is assumed
 * that this conversion happens on native serializable script values such values
 * from native DOM calls.
 *
 * [object] is the result of a structured clone operation.
 *
 * If necessary, JavaScript Dates are converted into Dart Dates.
 *
 * If [mustCopy] is [:true:], the entire object is copied and the original input
 * is not mutated.  This should be the case where Dart and JavaScript code can
 * access the value, for example, via multiple event listeners for
 * MessageEvents.  Mutating the object to make it more 'Dart-like' would corrupt
 * the value as seen from the JavaScript listeners.
 */
abstract class _AcceptStructuredClone {
  // TODO(sra): Replace slots with identity hash table.
  var values = [];
  var copies = []; // initially 'null', 'true' during initial DFS, then a copy.
  bool mustCopy = false;

  int findSlot(value) {
    int length = values.length;
    for (int i = 0; i < length; i++) {
      if (identicalInJs(values[i], value)) return i;
    }
    values.add(value);
    copies.add(null);
    return length;
  }

  /// Are the two objects identical, but taking into account that two JsObject
  /// wrappers may not be identical, but their underlying Js Object might be.
  bool identicalInJs(a, b);
  readSlot(int i) => copies[i];
  writeSlot(int i, x) {
    copies[i] = x;
  }

  /// Iterate over the JS properties.
  forEachJsField(object, action(key, value));

  /// Create a new Dart list of the given length. May create a native List or
  /// a JsArray, depending if we're in Dartium or dart2js.
  List newDartList(length);

  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 (isJavaScriptDate(e)) {
      return convertNativeToDart_DateTime(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 slot = findSlot(e);
      var copy = readSlot(slot);
      if (copy != null) return copy;
      copy = {};

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

    if (isJavaScriptArray(e)) {
      var l = JS('List', '#', e);
      var slot = findSlot(l);
      var copy = JS('List', '#', readSlot(slot));
      if (copy != null) return copy;

      int length = l.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) : l;
      writeSlot(slot, copy);

      for (int i = 0; i < length; i++) {
        copy[i] = walk(l[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;
  }
}

// Conversions for ContextAttributes.
//
// On Firefox, the returned ContextAttributes is a plain object.
class ContextAttributes {
  bool alpha;
  bool antialias;
  bool depth;
  bool premultipliedAlpha;
  bool preserveDrawingBuffer;
  bool stencil;
  bool failIfMajorPerformanceCaveat;

  ContextAttributes(
      this.alpha,
      this.antialias,
      this.depth,
      this.failIfMajorPerformanceCaveat,
      this.premultipliedAlpha,
      this.preserveDrawingBuffer,
      this.stencil);
}

convertNativeToDart_ContextAttributes(nativeContextAttributes) {
  // On Firefox the above test fails because ContextAttributes is a plain
  // object so we create a _TypedContextAttributes.

  return new ContextAttributes(
      JS('var', '#.alpha', nativeContextAttributes),
      JS('var', '#.antialias', nativeContextAttributes),
      JS('var', '#.depth', nativeContextAttributes),
      JS('var', '#.failIfMajorPerformanceCaveat', nativeContextAttributes),
      JS('var', '#.premultipliedAlpha', nativeContextAttributes),
      JS('var', '#.preserveDrawingBuffer', nativeContextAttributes),
      JS('var', '#.stencil', nativeContextAttributes));
}

// Conversions for ImageData
//
// On Firefox, the returned ImageData is a plain object.

class _TypedImageData implements ImageData {
  final Uint8ClampedList data;
  final int height;
  final int width;

  _TypedImageData(this.data, this.height, this.width);
}

ImageData convertNativeToDart_ImageData(nativeImageData) {
  // None of the native getters that return ImageData are declared as returning
  // [ImageData] since that is incorrect for FireFox, which returns a plain
  // Object.  So we need something that tells the compiler that the ImageData
  // class has been instantiated.
  // TODO(sra): Remove this when all the ImageData returning APIs have been
  // annotated as returning the union ImageData + Object.
  JS('ImageData', '0');

  if (nativeImageData is ImageData) {
    // Fix for Issue 16069: on IE, the `data` field is a CanvasPixelArray which
    // has Array as the constructor property.  This interferes with finding the
    // correct interceptor.  Fix it by overwriting the constructor property.
    var data = nativeImageData.data;
    if (JS('bool', '#.constructor === Array', data)) {
      if (JS('bool', 'typeof CanvasPixelArray !== "undefined"')) {
        JS('void', '#.constructor = CanvasPixelArray', data);
        // This TypedArray property is missing from CanvasPixelArray.
        JS('void', '#.BYTES_PER_ELEMENT = 1', data);
      }
    }

    return nativeImageData;
  }

  // On Firefox the above test fails because [nativeImageData] is a plain
  // object.  So we create a _TypedImageData.

  return new _TypedImageData(
      JS('NativeUint8ClampedList', '#.data', nativeImageData),
      JS('var', '#.height', nativeImageData),
      JS('var', '#.width', nativeImageData));
}

// We can get rid of this conversion if _TypedImageData implements the fields
// with native names.
convertDartToNative_ImageData(ImageData imageData) {
  if (imageData is _TypedImageData) {
    return JS('', '{data: #, height: #, width: #}', imageData.data,
        imageData.height, imageData.width);
  }
  return imageData;
}

const String _serializedScriptValue = 'num|String|bool|'
    'JSExtendableArray|=Object|'
    'Blob|File|NativeByteBuffer|NativeTypedData'
    // TODO(sra): Add Date, RegExp.
    ;
const annotation_Creates_SerializedScriptValue =
    const Creates(_serializedScriptValue);
const annotation_Returns_SerializedScriptValue =
    const Returns(_serializedScriptValue);
