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

/// An abstraction of the JS types
abstract class JSType {
  const JSType();

  /// True if this type is built-in to JS, and we use the values unwrapped.
  /// For these types we generate a calling convention via static
  /// "extension methods". This allows types to be extended without adding
  /// extensions directly on the prototype.
  bool get isPrimitive;

  /// Is this type known to be definitively primitive
  /// (using the JS notion of primitive)
  bool get isPrimitiveInJS;

  /// Can a non-null element of this type potentially be interpreted
  /// as false in JS.
  bool get isFalsey;

  /// The JS `typeof` value, if unambiguous.
  String? get primitiveTypeOf => null;

  static const jsBoolean = JSBoolean();
  static const jsNumber = JSNumber();
  static const jsNull = JSNull();
  static const jsObject = JSObject();
  static const jsString = JSString();
  static const jsUnknown = JSUnknown();
  // TODO(jmesserly): add JSFunction that maps to Dart's `Function` type.
}

/// Inhabited by booleans (including JSBool), null, and undefined
class JSBoolean extends JSType {
  const JSBoolean();
  @override
  bool get isPrimitive => true;
  @override
  bool get isPrimitiveInJS => true;
  @override
  bool get isFalsey => true;
  @override
  String get primitiveTypeOf => 'boolean';
}

/// Inhabited by numbers, null, and undefined
/// In practice, this is 4 types: num, int, double, and _interceptors.JSNumber.
///
/// _interceptors.JSNumber is the type that actually "implements" all numbers,
/// hence it's a subtype of int and double (and num).
/// It's defined in our "dart:_interceptors".
class JSNumber extends JSType {
  const JSNumber();
  @override
  bool get isPrimitive => true;
  @override
  bool get isPrimitiveInJS => true;
  @override
  bool get isFalsey => true;
  @override
  String get primitiveTypeOf => 'number';
}

/// Inhabited by null and undefined
class JSNull extends JSType {
  const JSNull();
  @override
  bool get isPrimitive => false;
  @override
  bool get isPrimitiveInJS => false;
  @override
  bool get isFalsey => true;
}

/// Inhabited by objects, null, and undefined
class JSObject extends JSType {
  const JSObject();
  @override
  bool get isPrimitive => false;
  @override
  bool get isPrimitiveInJS => false;
  @override
  bool get isFalsey => false;
}

/// Inhabited by strings (including JSString), null, and undefined
class JSString extends JSType {
  const JSString();
  @override
  bool get isPrimitive => true;
  @override
  bool get isPrimitiveInJS => false;
  @override
  bool get isFalsey => true;
  @override
  String get primitiveTypeOf => 'string';
}

/// Inhabitance not statically known
class JSUnknown extends JSType {
  const JSUnknown();
  @override
  bool get isPrimitive => false;
  @override
  bool get isPrimitiveInJS => false;
  @override
  bool get isFalsey => true;
}

abstract class SharedJSTypeRep<DartType> {
  JSType typeFor(DartType type);

  bool isNumber(DartType type) => typeFor(type) is JSNumber;

  bool isBoolean(DartType type) => typeFor(type) is JSBoolean;

  /// Is this type known to be represented as Object or Null in JS.
  bool isObjectOrNull(DartType t) {
    var rep = typeFor(t);
    return rep is JSObject || rep is JSNull;
  }

  bool isUnknown(DartType t) => typeFor(t) is JSUnknown;

  bool isPrimitive(DartType t) => typeFor(t).isPrimitive;

  bool isPrimitiveInJS(DartType t) => typeFor(t).isPrimitiveInJS;

  bool binaryOperationIsPrimitive(DartType leftT, DartType rightT) =>
      isPrimitiveInJS(leftT) && isPrimitiveInJS(rightT);

  bool unaryOperationIsPrimitive(DartType t) => isPrimitiveInJS(t);

  /// True if the JS double equals (`==`) comparison on the representation
  /// of these two types could potentially cause a conversion.
  bool equalityMayConvert(DartType t0, DartType t1) => !equalOrNull(t0, t1);

  // Are t0 and t1 known to either be represented by the same type
  // or else one or both of them is represented by Null
  bool equalOrNull(DartType t0, DartType t1) {
    var rep0 = typeFor(t0);
    var rep1 = typeFor(t1);
    if (rep0 is JSNull || rep1 is JSNull) return true;
    return rep0 == rep1 && rep0 is! JSUnknown;
  }
}
