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

import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
import '../elements/entities.dart';
import '../elements/names.dart';
import '../elements/types.dart' show DartType;
import '../ir/class_relation.dart';
import '../serialization/serialization.dart';
import '../universe/selector.dart';
import '../universe/world_builder.dart';
import '../universe/use.dart';
import '../world_interfaces.dart';
import 'abstract_value_domain.dart';
import 'abstract_value_strategy.dart';

class WrappedAbstractValue implements AbstractValue {
  final AbstractValue _abstractValue;
  const WrappedAbstractValue(this._abstractValue);

  @override
  bool operator ==(var other) {
    if (identical(this, other)) return true;
    if (other is! WrappedAbstractValue) return false;
    return _abstractValue == other._abstractValue;
  }

  @override
  int get hashCode {
    return _abstractValue.hashCode;
  }

  @override
  String toString() => _abstractValue.toString();
}

AbstractValue? unwrapOrNull(WrappedAbstractValue? wrapped) {
  return wrapped?._abstractValue;
}

WrappedAbstractValue? wrapOrNull(AbstractValue? abstractValue) {
  return abstractValue == null ? null : WrappedAbstractValue(abstractValue);
}

class WrappedAbstractValueDomain implements AbstractValueDomain {
  final AbstractValueDomain _abstractValueDomain;
  const WrappedAbstractValueDomain(this._abstractValueDomain);

  @override
  AbstractValue get internalTopType =>
      WrappedAbstractValue(_abstractValueDomain.internalTopType);

  @override
  AbstractValue get dynamicType =>
      WrappedAbstractValue(_abstractValueDomain.dynamicType);

  @override
  void writeAbstractValueToDataSink(
      DataSinkWriter sink, covariant WrappedAbstractValue value) {
    _abstractValueDomain.writeAbstractValueToDataSink(
        sink, value._abstractValue);
  }

  @override
  AbstractValue readAbstractValueFromDataSource(DataSourceReader source) =>
      WrappedAbstractValue(
          _abstractValueDomain.readAbstractValueFromDataSource(source));

  @override
  String getCompactText(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.getCompactText(value._abstractValue);

  @override
  AbstractBool isFixedLengthJsIndexable(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isFixedLengthJsIndexable(value._abstractValue);

  @override
  AbstractBool isJsIndexableAndIterable(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isJsIndexableAndIterable(value._abstractValue);

  @override
  AbstractBool isJsIndexable(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isJsIndexable(value._abstractValue);

  @override
  MemberEntity? locateSingleMember(
          covariant WrappedAbstractValue receiver, Selector selector) =>
      _abstractValueDomain.locateSingleMember(
          receiver._abstractValue, selector);

  @override
  AbstractBool isIn(covariant WrappedAbstractValue subset,
          covariant WrappedAbstractValue superset) =>
      _abstractValueDomain.isIn(subset._abstractValue, superset._abstractValue);

  @override
  AbstractBool needsNoSuchMethodHandling(
          covariant WrappedAbstractValue receiver, Selector selector) =>
      _abstractValueDomain.needsNoSuchMethodHandling(
          receiver._abstractValue, selector);

  @override
  AbstractBool isTargetingMember(covariant WrappedAbstractValue receiver,
          MemberEntity member, Name name) =>
      _abstractValueDomain.isTargetingMember(
          receiver._abstractValue, member, name);

  @override
  AbstractValue computeReceiver(Iterable<MemberEntity> members) =>
      WrappedAbstractValue(_abstractValueDomain.computeReceiver(members));

  @override
  PrimitiveConstantValue? getPrimitiveValue(
          covariant WrappedAbstractValue value) =>
      _abstractValueDomain.getPrimitiveValue(value._abstractValue);

  @override
  AbstractValue createPrimitiveValue(
          covariant WrappedAbstractValue originalValue,
          PrimitiveConstantValue value) =>
      WrappedAbstractValue(_abstractValueDomain.createPrimitiveValue(
          originalValue._abstractValue, value));

  @override
  bool isPrimitiveValue(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isPrimitiveValue(value._abstractValue);

  @override
  MemberEntity? getAllocationElement(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.getAllocationElement(value._abstractValue);

  @override
  Object? getAllocationNode(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.getAllocationNode(value._abstractValue);

  @override
  AbstractValue getGeneralization(covariant WrappedAbstractValue value) =>
      WrappedAbstractValue(
          _abstractValueDomain.getGeneralization(unwrapOrNull(value))!);

  @override
  bool isSpecializationOf(covariant WrappedAbstractValue specialization,
          covariant WrappedAbstractValue generalization) =>
      _abstractValueDomain.isSpecializationOf(
          specialization._abstractValue, generalization._abstractValue);

  @override
  AbstractValue getDictionaryValueForKey(
          covariant WrappedAbstractValue value, String key) =>
      WrappedAbstractValue(_abstractValueDomain.getDictionaryValueForKey(
          value._abstractValue, key));

  @override
  bool containsDictionaryKey(
          covariant WrappedAbstractValue value, String key) =>
      _abstractValueDomain.containsDictionaryKey(value._abstractValue, key);

  @override
  AbstractValue createDictionaryValue(
      covariant WrappedAbstractValue? originalValue,
      Object? allocationNode,
      MemberEntity? allocationElement,
      covariant WrappedAbstractValue key,
      covariant WrappedAbstractValue value,
      covariant Map<String, AbstractValue> mappings) {
    return WrappedAbstractValue(_abstractValueDomain.createDictionaryValue(
        originalValue?._abstractValue,
        allocationNode,
        allocationElement,
        key._abstractValue,
        value._abstractValue, {
      for (var entry in mappings.entries)
        entry.key: (entry.value as WrappedAbstractValue)._abstractValue
    }));
  }

  @override
  bool isDictionary(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isDictionary(value._abstractValue);

  @override
  AbstractValue getMapValueType(covariant WrappedAbstractValue value) =>
      WrappedAbstractValue(
          _abstractValueDomain.getMapValueType(value._abstractValue));

  @override
  AbstractValue getMapKeyType(covariant WrappedAbstractValue value) =>
      WrappedAbstractValue(
          _abstractValueDomain.getMapKeyType(value._abstractValue));

  @override
  AbstractValue createMapValue(
          covariant WrappedAbstractValue? originalValue,
          Object? allocationNode,
          MemberEntity? allocationElement,
          covariant WrappedAbstractValue key,
          covariant WrappedAbstractValue value) =>
      WrappedAbstractValue(_abstractValueDomain.createMapValue(
          originalValue?._abstractValue,
          allocationNode,
          allocationElement,
          key._abstractValue,
          value._abstractValue));

  @override
  bool isMap(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isMap(value._abstractValue);

  @override
  AbstractValue getSetElementType(covariant WrappedAbstractValue value) =>
      WrappedAbstractValue(
          _abstractValueDomain.getSetElementType(value._abstractValue));

  @override
  AbstractValue createSetValue(
          covariant WrappedAbstractValue? originalValue,
          Object? allocationNode,
          MemberEntity? allocationElement,
          covariant WrappedAbstractValue elementType) =>
      WrappedAbstractValue(_abstractValueDomain.createSetValue(
          originalValue?._abstractValue,
          allocationNode,
          allocationElement,
          elementType._abstractValue));

  @override
  bool isSet(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isSet(value._abstractValue);

  @override
  int? getContainerLength(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.getContainerLength(value._abstractValue);

  @override
  AbstractValue getContainerElementType(covariant WrappedAbstractValue value) =>
      WrappedAbstractValue(
          _abstractValueDomain.getContainerElementType(value._abstractValue));

  @override
  AbstractValue createContainerValue(
          covariant WrappedAbstractValue? originalValue,
          Object? allocationNode,
          MemberEntity? allocationElement,
          covariant WrappedAbstractValue elementType,
          int? length) =>
      WrappedAbstractValue(_abstractValueDomain.createContainerValue(
          originalValue?._abstractValue,
          allocationNode,
          allocationElement,
          elementType._abstractValue,
          length));

  @override
  bool isContainer(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isContainer(value._abstractValue);

  @override
  AbstractValue computeAbstractValueForConstant(
          covariant ConstantValue value) =>
      WrappedAbstractValue(
          _abstractValueDomain.computeAbstractValueForConstant(value));

  @override
  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) {
    return wrapOrNull(_abstractValueDomain
        .getAbstractValueForNativeMethodParameterType(type));
  }

  @override
  AbstractBool containsAll(covariant WrappedAbstractValue a) =>
      _abstractValueDomain.containsAll(a._abstractValue);

  @override
  AbstractBool areDisjoint(
          covariant WrappedAbstractValue a, covariant WrappedAbstractValue b) =>
      _abstractValueDomain.areDisjoint(a._abstractValue, b._abstractValue);

  @override
  AbstractValue intersection(
          covariant WrappedAbstractValue a, covariant WrappedAbstractValue b) =>
      WrappedAbstractValue(_abstractValueDomain.intersection(
          a._abstractValue, b._abstractValue));

  @override
  AbstractValue unionOfMany(covariant Iterable<AbstractValue> values) {
    List<AbstractValue> unwrapped_Values = values
        .map((element) => (element as WrappedAbstractValue)._abstractValue)
        .toList();
    return WrappedAbstractValue(
        _abstractValueDomain.unionOfMany(unwrapped_Values));
  }

  @override
  AbstractValue union(
          covariant WrappedAbstractValue a, covariant WrappedAbstractValue b) =>
      WrappedAbstractValue(
          _abstractValueDomain.union(a._abstractValue, b._abstractValue));

  @override
  AbstractBool isPrimitiveOrNull(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isPrimitiveOrNull(value._abstractValue);

  @override
  AbstractBool isStringOrNull(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isStringOrNull(value._abstractValue);

  @override
  AbstractBool isString(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isString(value._abstractValue);

  @override
  AbstractBool isBooleanOrNull(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isBooleanOrNull(value._abstractValue);

  @override
  AbstractBool isBoolean(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isBoolean(value._abstractValue);

  @override
  AbstractBool isTruthy(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isTruthy(value._abstractValue);

  @override
  AbstractBool isNumberOrNull(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isNumberOrNull(value._abstractValue);

  @override
  AbstractBool isNumber(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isNumber(value._abstractValue);

  @override
  AbstractBool isIntegerOrNull(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isIntegerOrNull(value._abstractValue);

  @override
  AbstractBool isPositiveIntegerOrNull(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isPositiveIntegerOrNull(value._abstractValue);

  @override
  AbstractBool isPositiveInteger(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isPositiveInteger(value._abstractValue);

  @override
  AbstractBool isUInt31(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isUInt31(value._abstractValue);

  @override
  AbstractBool isUInt32(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isUInt32(value._abstractValue);

  @override
  AbstractBool isInteger(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isInteger(value._abstractValue);

  @override
  AbstractBool isInterceptor(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isInterceptor(value._abstractValue);

  @override
  AbstractBool isPrimitiveString(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isPrimitiveString(value._abstractValue);

  @override
  AbstractBool isArray(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isArray(value._abstractValue);

  @override
  AbstractBool isMutableIndexable(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isMutableIndexable(value._abstractValue);

  @override
  AbstractBool isMutableArray(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isMutableArray(value._abstractValue);

  @override
  AbstractBool isExtendableArray(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isExtendableArray(value._abstractValue);

  @override
  AbstractBool isFixedArray(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isFixedArray(value._abstractValue);

  @override
  AbstractBool isIndexablePrimitive(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isIndexablePrimitive(value._abstractValue);

  @override
  AbstractBool isPrimitiveBoolean(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isPrimitiveBoolean(value._abstractValue);

  @override
  AbstractBool isPrimitiveNumber(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isPrimitiveNumber(value._abstractValue);

  @override
  AbstractBool isPrimitive(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isPrimitive(value._abstractValue);

  @override
  AbstractBool isNull(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isNull(value._abstractValue);

  @override
  AbstractBool isLateSentinel(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isLateSentinel(value._abstractValue);

  @override
  ClassEntity? getExactClass(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.getExactClass(value._abstractValue);

  @override
  AbstractBool isExact(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isExact(value._abstractValue);

  @override
  AbstractBool isEmpty(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isEmpty(value._abstractValue);

  @override
  AbstractBool isInstanceOf(
          covariant WrappedAbstractValue value, ClassEntity cls) =>
      _abstractValueDomain.isInstanceOf(value._abstractValue, cls);

  @override
  AbstractBool isInstanceOfOrNull(
          covariant WrappedAbstractValue value, ClassEntity cls) =>
      _abstractValueDomain.isInstanceOfOrNull(value._abstractValue, cls);

  @override
  AbstractBool containsOnlyType(
          covariant WrappedAbstractValue value, ClassEntity cls) =>
      _abstractValueDomain.containsOnlyType(value._abstractValue, cls);

  @override
  AbstractBool containsType(
          covariant WrappedAbstractValue value, ClassEntity cls) =>
      _abstractValueDomain.containsType(value._abstractValue, cls);

  @override
  AbstractValue includeNull(covariant WrappedAbstractValue value) =>
      WrappedAbstractValue(
          _abstractValueDomain.includeNull(value._abstractValue));

  @override
  AbstractValue excludeNull(covariant WrappedAbstractValue value) =>
      WrappedAbstractValue(
          _abstractValueDomain.excludeNull(value._abstractValue));

  @override
  AbstractValue includeLateSentinel(covariant WrappedAbstractValue value) =>
      WrappedAbstractValue(
          _abstractValueDomain.includeLateSentinel(value._abstractValue));

  @override
  AbstractValue excludeLateSentinel(covariant WrappedAbstractValue value) =>
      WrappedAbstractValue(
          _abstractValueDomain.excludeLateSentinel(value._abstractValue));

  @override
  AbstractBool couldBeTypedArray(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.couldBeTypedArray(value._abstractValue);

  @override
  AbstractBool isTypedArray(covariant WrappedAbstractValue value) =>
      _abstractValueDomain.isTypedArray(value._abstractValue);

  @override
  AbstractValue createNullableSubtype(ClassEntity cls) =>
      WrappedAbstractValue(_abstractValueDomain.createNullableSubtype(cls));

  @override
  AbstractValue createNonNullSubtype(ClassEntity cls) =>
      WrappedAbstractValue(_abstractValueDomain.createNonNullSubtype(cls));

  @override
  AbstractValue createNonNullSubclass(ClassEntity cls) =>
      WrappedAbstractValue(_abstractValueDomain.createNonNullSubclass(cls));

  @override
  AbstractValue createNullableExact(ClassEntity cls) =>
      WrappedAbstractValue(_abstractValueDomain.createNullableExact(cls));

  @override
  AbstractValue createNonNullExact(ClassEntity cls) =>
      WrappedAbstractValue(_abstractValueDomain.createNonNullExact(cls));

  @override
  AbstractValueWithPrecision createFromStaticType(DartType type,
      {ClassRelation classRelation = ClassRelation.subtype,
      required bool nullable}) {
    var unwrapped = _abstractValueDomain.createFromStaticType(type,
        classRelation: classRelation, nullable: nullable);
    return AbstractValueWithPrecision(
        WrappedAbstractValue(unwrapped.abstractValue), unwrapped.isPrecise);
  }

  @override
  AbstractValue get asyncStarStreamType =>
      WrappedAbstractValue(_abstractValueDomain.asyncStarStreamType);

  @override
  AbstractValue get asyncFutureType =>
      WrappedAbstractValue(_abstractValueDomain.asyncFutureType);

  @override
  AbstractValue get syncStarIterableType =>
      WrappedAbstractValue(_abstractValueDomain.syncStarIterableType);

  @override
  AbstractValue get emptyType =>
      WrappedAbstractValue(_abstractValueDomain.emptyType);

  @override
  AbstractValue get constMapType =>
      WrappedAbstractValue(_abstractValueDomain.constMapType);

  @override
  AbstractValue get constSetType =>
      WrappedAbstractValue(_abstractValueDomain.constSetType);

  @override
  AbstractValue get constListType =>
      WrappedAbstractValue(_abstractValueDomain.constListType);

  @override
  AbstractValue get positiveIntType =>
      WrappedAbstractValue(_abstractValueDomain.positiveIntType);

  @override
  AbstractValue get uint32Type =>
      WrappedAbstractValue(_abstractValueDomain.uint32Type);

  @override
  AbstractValue get uint31Type =>
      WrappedAbstractValue(_abstractValueDomain.uint31Type);

  @override
  AbstractValue get fixedListType =>
      WrappedAbstractValue(_abstractValueDomain.fixedListType);

  @override
  AbstractValue get growableListType =>
      WrappedAbstractValue(_abstractValueDomain.growableListType);

  @override
  AbstractValue get mutableArrayType =>
      WrappedAbstractValue(_abstractValueDomain.mutableArrayType);

  @override
  AbstractValue get nullType =>
      WrappedAbstractValue(_abstractValueDomain.nullType);

  @override
  AbstractValue get nonNullType =>
      WrappedAbstractValue(_abstractValueDomain.nonNullType);

  @override
  AbstractValue get lateSentinelType =>
      WrappedAbstractValue(_abstractValueDomain.lateSentinelType);

  @override
  AbstractValue get mapType =>
      WrappedAbstractValue(_abstractValueDomain.mapType);

  @override
  AbstractValue get setType =>
      WrappedAbstractValue(_abstractValueDomain.setType);

  @override
  AbstractValue get listType =>
      WrappedAbstractValue(_abstractValueDomain.listType);

  @override
  AbstractValue get stringType =>
      WrappedAbstractValue(_abstractValueDomain.stringType);

  @override
  AbstractValue get numType =>
      WrappedAbstractValue(_abstractValueDomain.numType);

  @override
  AbstractValue get numNotIntType =>
      WrappedAbstractValue(_abstractValueDomain.numNotIntType);

  @override
  AbstractValue get intType =>
      WrappedAbstractValue(_abstractValueDomain.intType);

  @override
  AbstractValue get boolType =>
      WrappedAbstractValue(_abstractValueDomain.boolType);

  @override
  AbstractValue get functionType =>
      WrappedAbstractValue(_abstractValueDomain.functionType);

  @override
  AbstractValue get typeType =>
      WrappedAbstractValue(_abstractValueDomain.typeType);
}

class WrappedAbstractValueStrategy implements AbstractValueStrategy {
  final AbstractValueStrategy _abstractValueStrategy;
  const WrappedAbstractValueStrategy(this._abstractValueStrategy);

  @override
  AbstractValueDomain createDomain(JClosedWorld closedWorld) {
    return WrappedAbstractValueDomain(
        _abstractValueStrategy.createDomain(closedWorld));
  }

  @override
  SelectorConstraintsStrategy createSelectorStrategy() {
    return WrappedSelectorStrategy(
        _abstractValueStrategy.createSelectorStrategy());
  }
}

class WrappedSelectorStrategy implements SelectorConstraintsStrategy {
  final SelectorConstraintsStrategy _selectorConstraintsStrategy;
  const WrappedSelectorStrategy(this._selectorConstraintsStrategy);

  @override
  UniverseSelectorConstraints createSelectorConstraints(
      Selector selector, Object? initialConstraint) {
    return WrappedUniverseSelectorConstraints(
        _selectorConstraintsStrategy.createSelectorConstraints(
            selector,
            initialConstraint == null
                ? null
                : (initialConstraint as WrappedAbstractValue)._abstractValue));
  }

  @override
  bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member,
      covariant JClosedWorld world) {
    return _selectorConstraintsStrategy.appliedUnnamed(
        dynamicUse.withReceiverConstraint(unwrapOrNull(
            dynamicUse.receiverConstraint as WrappedAbstractValue?)),
        member,
        world);
  }
}

class WrappedUniverseSelectorConstraints
    implements UniverseSelectorConstraints {
  final UniverseSelectorConstraints _universeSelectorConstraints;
  const WrappedUniverseSelectorConstraints(this._universeSelectorConstraints);

  @override
  bool addReceiverConstraint(Object? constraint) =>
      _universeSelectorConstraints.addReceiverConstraint(constraint == null
          ? null
          : (constraint as WrappedAbstractValue)._abstractValue);

  @override
  bool needsNoSuchMethodHandling(Selector selector, World world) =>
      _universeSelectorConstraints.needsNoSuchMethodHandling(selector, world);

  @override
  bool canHit(MemberEntity element, Name name, World world) =>
      _universeSelectorConstraints.canHit(element, name, world);

  @override
  String toString() => 'WrappedUniverseSelectorConstraints:$hashCode';
}
