part of html_common;

/// Converts native values to their Dart equivalent
///
/// This includes other maps, lists, or values that don't need a conversion e.g.
/// bool, String.
_convertNativeToDart_Value(value) {
  if (value == null) return value;
  if (value is String || value is num || value is bool) return value;
  if (isJavaScriptSimpleObject(value)) {
    return convertNativeToDart_Dictionary(value);
  }
  if (JS('bool', 'Array.isArray(#)', value)) {
    List values = [];
    for (var i = 0; i < JS<int>('int', '#.length', value); i++) {
      values.add(_convertNativeToDart_Value(JS('var', '#[#]', value, i)));
    }

    return values;
  }
  return value;
}

/// Recursively converts a JavaScript object with properties into a Dart Map.
/// This includes maps, lists, and other values that don't need a conversion.
Map<String, dynamic>? convertNativeToDart_Dictionary(object) {
  if (object == null) return null;
  var dict = <String, dynamic>{};
  var keys = JS<JSExtendableArray>(
      'JSExtendableArray', 'Object.getOwnPropertyNames(#)', object);
  for (final key in keys) {
    dict[JS('String', '#', key)] =
        _convertNativeToDart_Value(JS('var', '#[#]', object, key));
  }
  return dict;
}

/// Converts values that occur within a Dart map for map conversion.
///
/// This includes other maps, lists, or values that don't need a conversion e.g.
/// bool, String.
_convertDartToNative_Value(Object? value) {
  if (value == null) return value;
  if (value is String || value is num || value is bool) return value;
  if (value is Map) return convertDartToNative_Dictionary(value);
  if (value is List) {
    var array = JS('var', '[]');
    value.forEach((element) {
      JS('void', '#.push(#)', array, _convertDartToNative_Value(element));
    });
    value = array;
  }
  return value;
}

/// Converts a potentially nested Dart map to a JavaScript object with
/// properties.
///
/// This method requires that the values within the map are either maps
/// themselves, lists, or do not need a conversion.
convertDartToNative_Dictionary(Map? dict, [void postCreate(Object? f)?]) {
  if (dict == null) return null;
  var object = JS('var', '{}');
  if (postCreate != null) {
    postCreate(object);
  }
  dict.forEach((key, value) {
    JS('void', '#[#] = #', object, key, _convertDartToNative_Value(value));
  });
  return object;
}

/**
 * Ensures that the input is a JavaScript Array.
 *
 * Creates a new JavaScript array if necessary, otherwise returns the original.
 */
List convertDartToNative_StringArray(List<String> input) {
  // TODO(sra).  Implement this.
  return input;
}

DateTime convertNativeToDart_DateTime(date) {
  int millisSinceEpoch = JS('int', '#.getTime()', date);
  return new DateTime.fromMillisecondsSinceEpoch(millisSinceEpoch, isUtc: true);
}

convertDartToNative_DateTime(DateTime date) {
  return JS('', 'new Date(#)', date.millisecondsSinceEpoch);
}

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

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

class _StructuredCloneDart2Js extends _StructuredClone {
  JSObject newJsObject() => JS('JSObject', '{}');

  void forEachObjectKey(object, action(key, value)) {
    for (final key
        in JS('returns:JSExtendableArray;new:true', 'Object.keys(#)', object)) {
      action(key, JS('var', '#[#]', object, key));
    }
  }

  void putIntoObject(object, key, value) =>
      JS('void', '#[#] = #', object, key, value);

  newJsMap() => JS('var', '{}');
  putIntoMap(map, key, value) => JS('void', '#[#] = #', map, key, value);
  newJsList(length) => JS('JSExtendableArray', 'new Array(#)', length);
  cloneNotRequired(e) =>
      (e is NativeByteBuffer || e is NativeTypedData || e is MessagePort);
}

class _AcceptStructuredCloneDart2Js extends _AcceptStructuredClone {
  List newJsList(length) => JS('JSExtendableArray', 'new Array(#)', length);
  List newDartList(length) => newJsList(length);
  bool identicalInJs(a, b) => identical(a, b);

  void forEachJsField(object, action(key, value)) {
    for (final key in JS('JSExtendableArray', 'Object.keys(#)', object)) {
      action(key, JS('var', '#[#]', object, key));
    }
  }
}

bool isJavaScriptDate(value) => JS('bool', '# instanceof Date', value);
bool isJavaScriptRegExp(value) => JS('bool', '# instanceof RegExp', value);
bool isJavaScriptArray(value) => JS('bool', '# instanceof Array', value);
bool isJavaScriptSimpleObject(value) {
  var proto = JS('', 'Object.getPrototypeOf(#)', value);
  return JS('bool', '# === Object.prototype', proto) ||
      JS('bool', '# === null', proto);
}

bool isImmutableJavaScriptArray(value) =>
    JS('bool', r'!!(#.immutable$list)', value);
bool isJavaScriptPromise(value) =>
    JS('bool', r'typeof Promise != "undefined" && # instanceof Promise', value);

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