// Copyright (c) 2016, 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 `package:js` annotated JavaScript interop
/// objects in cases where the name to call is not known at runtime.
///
/// > [!Note]
/// > You should usually use `dart:js_interop` instead of this library.
/// > To learn more, check out the
/// > [JS interop documentation](https://dart.dev/interop/js-interop).
///
/// You should only use these methods when the same effect cannot be achieved
/// with `@JS()` annotations.
///
/// {@category Web (Legacy)}
@Deprecated('Use dart:js_interop instead.')
library dart.js_util;

export 'dart:js_interop' show NullRejectionException;

// Examples can assume:
// class JS { const JS(); }
// class Promise<T> {}

/// Recursively converts a JSON-like collection to JavaScript compatible
/// representation.
///
/// WARNING: performance of this method is much worse than other util
/// methods in this library. Only use this method as a last resort. Prefer
/// instead to use `@anonymous` `@JS()` annotated classes to create map-like
/// objects for JS interop.
///
/// If the argument are a [Map] or [Iterable], then they will be deeply
/// converted.  Maps are converted into JavaScript objects. Iterables are
/// converted into arrays. `@JS()` annotated objects are passed through
/// unmodified. Dart objects are also passed through unmodified, but their
/// members aren't usable from JavaScript.  The conversion logic for
/// primitives(numbers, bools, and Strings) is backend specific.
external dynamic jsify(Object? object);

external Object get globalThis;

external T newObject<T>();

external bool hasProperty(Object o, Object name);

external T getProperty<T>(Object o, Object name);

// A CFE transformation may optimize calls to `setProperty`, when [value] is
// statically known to be a non-function.
external T setProperty<T>(Object o, Object name, T? value);

// A CFE transformation may optimize calls to `callMethod` when [args] is a
// a list literal or const list containing at most 4 values, all of which are
// statically known to be non-functions.
external T callMethod<T>(Object o, Object method, List<Object?> args);

/// Check whether [o] is an instance of [type].
///
/// The value in [type] is expected to be a JS-interop object that
/// represents a valid JavaScript constructor function.
external bool instanceof(Object? o, Object type);

external T callConstructor<T>(Object constr, List<Object?>? arguments);

/// Perform JavaScript addition (`+`) on two values.
external T add<T>(Object? first, Object? second);

/// Perform JavaScript subtraction (`-`) on two values.
external T subtract<T>(Object? first, Object? second);

/// Perform JavaScript multiplication (`*`) on two values.
external T multiply<T>(Object? first, Object? second);

/// Perform JavaScript division (`/`) on two values.
external T divide<T>(Object? first, Object? second);

/// Perform JavaScript exponentiation (`**`) on two values.
external T exponentiate<T>(Object? first, Object? second);

/// Perform JavaScript remainder (`%`) on two values.
external T modulo<T>(Object? first, Object? second);

/// Perform JavaScript equality comparison (`==`) on two values.
external bool equal<T>(Object? first, Object? second);

/// Perform JavaScript strict equality comparison (`===`) on two values.
external bool strictEqual<T>(Object? first, Object? second);

/// Perform JavaScript inequality comparison (`!=`) on two values.
external bool notEqual<T>(Object? first, Object? second);

/// Perform JavaScript strict inequality comparison (`!==`) on two values.
external bool strictNotEqual<T>(Object? first, Object? second);

/// Perform JavaScript greater than comparison (`>`) of two values.
external bool greaterThan<T>(Object? first, Object? second);

/// Perform JavaScript greater than or equal comparison (`>=`) of two values.
external bool greaterThanOrEqual<T>(Object? first, Object? second);

/// Perform JavaScript less than comparison (`<`) of two values.
external bool lessThan<T>(Object? first, Object? second);

/// Perform JavaScript less than or equal comparison (`<=`) of two values.
external bool lessThanOrEqual<T>(Object? first, Object? second);

/// Perform JavaScript `typeof` operator on the given object and determine if
/// the result is equal to the given type. Exposes the whole `typeof` equal
/// expression to maximize browser optimization.
external bool typeofEquals<T>(Object? o, String type);

/// Perform JavaScript logical not (`!`) on the given object.
external T not<T>(Object? o);

/// Determines if the given object is truthy or falsy.
external bool isTruthy<T>(Object? o);

/// Perform JavaScript logical or comparison (`||`) of two expressions.
external T or<T>(Object? first, Object? second);

/// Perform JavaScript logical and comparison (`&&`) of two expressions.
external T and<T>(Object? first, Object? second);

/// Perform JavaScript delete operator (`delete`) on the given property of the
/// given object.
external bool delete<T>(Object o, Object property);

/// Perform JavaScript unsigned right shift operator (`>>>`) on the given left
/// operand by the amount specified by the given right operand.
external num unsignedRightShift(Object? leftOperand, Object? rightOperand);

/// Converts a JavaScript Promise to a Dart [Future].
///
/// ```dart
/// // ignore: deprecated_member_use_from_same_package, deprecated_member_use
/// import 'dart:js_util';
///
/// // ignore: deprecated_member_use_from_same_package, deprecated_member_use
/// import 'package:js/js.dart';
///
/// @JS()
/// class Promise<T> {}
///
/// @JS()
/// external Promise<num> get threePromise; // Resolves to 3
///
/// void main() async {
///   final Future<num> threeFuture = promiseToFuture(threePromise);
///
///   final three = await threeFuture; // == 3
/// }
/// ```
external Future<T> promiseToFuture<T>(Object jsPromise);

Object? _getConstructor(String constructorName) =>
    getProperty(globalThis, constructorName);

/// Like [instanceof] only takes a [String] for the object name instead of a
/// constructor object.
bool instanceOfString(Object? element, String objectType) {
  Object? constructor = _getConstructor(objectType);
  return constructor != null && instanceof(element, constructor);
}

/// Returns the prototype of a given object. Equivalent to
/// `Object.getPrototypeOf`.
external Object? objectGetPrototypeOf(Object? object);

/// Returns the `Object` prototype. Equivalent to `Object.prototype`.
external Object? get objectPrototype;

/// Returns the keys for a given object. Equivalent to `Object.keys(object)`.
external List<Object?> objectKeys(Object? object);

/// Returns `true` if a given object is a JavaScript array.
external bool isJavaScriptArray(value);

/// Returns `true` if a given object is a simple JavaScript object.
external bool isJavaScriptSimpleObject(value);

/// Effectively the inverse of [jsify], [dartify] Takes a JavaScript object, and
/// converts it to a Dart based object. Only JS primitives, arrays, or 'map'
/// like JS objects are supported.
external Object? dartify(Object? o);

/// Given a `@staticInterop` type T and an instance [dartMock] of a Dart class
/// U that implements the external extension members of T, creates a forwarding
/// mock.
///
/// Optionally, you may provide a JS prototype object e.g. the JS value
/// `Window.prototype` using [proto]. This allows instanceof and is checks with
/// `@Native` types to pass with the returned forwarding mock.
///
/// When external extension members are called, they will forward to the
/// corresponding implementing member in [dartMock]. If U does not implement the
/// needed external extension members of T, or if U does not properly override
/// them, it will be considered a compile-time error.
///
/// For example:
///
/// ```
/// @JS()
/// @staticInterop
/// class JSClass {}
///
/// extension JSClassExtension on JSClass {
///   external String stringify(int param);
/// }
///
/// @JSExport()
/// class DartClass {
///   String stringify(num param) => param.toString();
/// }
///
/// ...
///
/// JSClass mock = createStaticInteropMock<JSClass, DartClass>(DartClass());
/// ```
external T createStaticInteropMock<T extends Object, U extends Object>(
  U dartMock, [
  Object? proto = null,
]);

/// Given a Dart object that is marked exportable, creates a JS object literal
/// that forwards to that Dart class. Look at the `@JSExport` annotation to
/// determine what constitutes "exportable" for a Dart class. The object literal
/// will be a map of export names (which are either the written instance member
/// names or their rename) to their respective Dart instance members.
///
/// For example:
///
/// ```
/// @JSExport()
/// class ExportCounter {
///   int value = 0;
///   String stringify() => value.toString();
/// }
///
/// @JS()
/// @staticInterop
/// class Counter {}
///
/// extension on Counter {
///   external int get value;
///   external set value(int val);
///   external String stringify();
/// }
///
/// ...
///
/// var export = ExportCounter();
/// var counter = createDartExport(export) as Counter;
/// export.value = 1;
/// Expect.isTrue(counter.value, export.value);
/// Expect.isTrue(counter.stringify(), export.stringify());
/// ```
external Object createDartExport<T extends Object>(T dartObject);

/// Returns a wrapper around function [f] that can be called from JavaScript
/// using `package:js` JavaScript interop.
///
/// The calling conventions in Dart web backends differ from JavaScript and so,
/// by default, it is not possible to call a Dart function directly. Wrapping
/// with `allowInterop` creates a function that can be called from JavaScript or
/// Dart. The semantics of the wrapped function are still more strict than
/// JavaScript, and the function will throw if called with too many or too few
/// arguments.
///
/// Calling this method repeatedly on a function will return the same result.
external F allowInterop<F extends Function>(F f);

/// Returns a wrapper around function [f] that can be called from JavaScript
/// using `package:js` JavaScript interop, passing JavaScript `this` as the
/// first argument.
///
/// See [allowInterop].
///
/// When called from Dart, `null` will be passed as the first argument.
external Function allowInteropCaptureThis(Function f);
