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

/// Utility methods to manipulate JavaScript objects dynamically.
///
/// This library is typically meant to be used when the names of properties or
/// methods are not known statically. This library is similar to `dart:js_util`,
/// except the methods here are extension methods that use JS types. This
/// allows code using these functions to also be compiled to WebAssembly.
///
/// In general, prefer to write JS interop interfaces and external static
/// interop members using `dart:js_interop`. This library is meant to work
/// around issues and help with migration from older JS interop libraries.
///
/// > [!NOTE]
/// > As the name suggests, usage of this library *can* be unsafe. This means
/// > that safe usage of these methods cannot necessarily be verified
/// > statically. Prefer using statically analyzable values like constants or
/// > literals for property or method names so that usage can be verified. This
/// > library should be used cautiously and only when the same effect cannot be
/// > achieved with static interop.
///
/// {@category Web}
library;

import 'dart:js_interop';

/// Utility methods to check, get, set, and call properties on a [JSObject].
///
/// See the [JavaScript specification](https://tc39.es/ecma262/#sec-object-type)
/// for more details on using properties.
extension JSObjectUnsafeUtilExtension on JSObject {
  /// Shorthand helper for [hasProperty] to check whether this [JSObject]
  /// contains the property key [property], but takes and returns a Dart value.
  bool has(String property) => hasProperty(property.toJS).toDart;

  /// Whether or not this [JSObject] contains the property key [property].
  external JSBoolean hasProperty(JSAny property);

  /// Shorthand helper for [getProperty] to get the value of the property key
  /// [property] of this [JSObject], but takes and returns a Dart value.
  JSAny? operator [](String property) => getProperty(property.toJS);

  /// The value of the property key [property] of this [JSObject].
  external R getProperty<R extends JSAny?>(JSAny property);

  /// Shorthand helper for [setProperty] to write the [value] of the property
  /// key [property] of this [JSObject], but takes a Dart value.
  void operator []=(String property, JSAny? value) =>
      setProperty(property.toJS, value);

  /// Write the [value] of property key [property] of this [JSObject].
  external void setProperty(JSAny property, JSAny? value);

  external JSAny? _callMethod(
    JSAny method, [
    JSAny? arg1,
    JSAny? arg2,
    JSAny? arg3,
    JSAny? arg4,
  ]);

  /// Calls [method] on this [JSObject] with up to four arguments.
  ///
  /// Returns the result of calling [method], which must be an [R].
  ///
  /// This helper doesn't allow passing nulls, as it determines whether an
  /// argument is passed based on whether it was null or not. Prefer
  /// [callMethodVarArgs] if you need to pass nulls.
  R callMethod<R extends JSAny?>(
    JSAny method, [
    JSAny? arg1,
    JSAny? arg2,
    JSAny? arg3,
    JSAny? arg4,
  ]) => _callMethod(method, arg1, arg2, arg3, arg4) as R;

  external JSAny? _callMethodVarArgs(JSAny method, [List<JSAny?>? arguments]);

  /// Calls [method] on this [JSObject] with a variable number of [arguments].
  ///
  /// Returns the result of calling [method], which must be an [R].
  R callMethodVarArgs<R extends JSAny?>(
    JSAny method, [
    List<JSAny?>? arguments,
  ]) => _callMethodVarArgs(method, arguments) as R;

  /// Deletes the property with key [property] from this [JSObject].
  external JSBoolean delete(JSAny property);
}

/// Utility methods to call [JSFunction]s as constructors.
extension JSFunctionUnsafeUtilExtension on JSFunction {
  external JSObject _callAsConstructor([
    JSAny? arg1,
    JSAny? arg2,
    JSAny? arg3,
    JSAny? arg4,
  ]);

  /// Calls this [JSFunction] as a constructor with up to four arguments.
  ///
  /// Returns the constructed object, which must be an [R].
  ///
  /// This helper doesn't allow passing nulls, as it determines whether an
  /// argument is passed based on whether it was null or not. Prefer
  /// [callAsConstructorVarArgs] if you need to pass nulls.
  // TODO(srujzs): The type bound should extend `JSObject`.
  R callAsConstructor<R>([
    JSAny? arg1,
    JSAny? arg2,
    JSAny? arg3,
    JSAny? arg4,
  ]) => _callAsConstructor(arg1, arg2, arg3, arg4) as R;

  external JSObject _callAsConstructorVarArgs([List<JSAny?>? arguments]);

  /// Calls this [JSFunction] as a constructor with a variable number of
  /// arguments.
  ///
  /// Returns the constructed [JSObject], which must be an [R].
  R callAsConstructorVarArgs<R extends JSObject>([List<JSAny?>? arguments]) =>
      _callAsConstructorVarArgs(arguments) as R;
}
