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

library dart2js.js_helpers.impact;

import '../common/elements.dart' show CommonElements, ElementEnvironment;
import '../common/names.dart';
import '../elements/types.dart' show InterfaceType;
import '../elements/entities.dart';
import '../universe/selector.dart';
import '../universe/world_impact.dart'
    show WorldImpact, WorldImpactBuilder, WorldImpactBuilderImpl;
import '../universe/use.dart';
import '../util/enumset.dart';
import '../options.dart';

/// Backend specific features required by a backend impact.
enum BackendFeature {
  needToInitializeIsolateAffinityTag,
  needToInitializeDispatchProperty,
}

/// A set of JavaScript backend dependencies.
class BackendImpact {
  final List<FunctionEntity> staticUses;
  final List<FunctionEntity> globalUses;
  final List<Selector> dynamicUses;
  final List<InterfaceType> instantiatedTypes;
  final List<ClassEntity> instantiatedClasses;
  final List<ClassEntity> globalClasses;
  final List<BackendImpact> otherImpacts;
  final EnumSet<BackendFeature> _features;

  const BackendImpact(
      {this.staticUses = const [],
      this.globalUses = const [],
      this.dynamicUses = const [],
      this.instantiatedTypes = const [],
      this.instantiatedClasses = const [],
      this.globalClasses = const [],
      this.otherImpacts = const [],
      EnumSet<BackendFeature> features = const EnumSet.fixed(0)})
      : this._features = features;

  Iterable<BackendFeature> get features =>
      _features.iterable(BackendFeature.values);

  WorldImpact createImpact(ElementEnvironment elementEnvironment) {
    WorldImpactBuilderImpl impactBuilder = WorldImpactBuilderImpl();
    registerImpact(impactBuilder, elementEnvironment);
    return impactBuilder;
  }

  /// Register this backend impact to the [worldImpactBuilder].
  void registerImpact(WorldImpactBuilder worldImpactBuilder,
      ElementEnvironment elementEnvironment) {
    for (FunctionEntity staticUse in staticUses) {
      assert((staticUse as dynamic) != null); // TODO(48820): Remove when sound.
      worldImpactBuilder.registerStaticUse(StaticUse.implicitInvoke(staticUse));
    }
    for (FunctionEntity staticUse in globalUses) {
      assert((staticUse as dynamic) != null); // TODO(48820): Remove when sound.
      worldImpactBuilder.registerStaticUse(StaticUse.implicitInvoke(staticUse));
    }
    for (Selector selector in dynamicUses) {
      assert((selector as dynamic) != null); // TODO(48820): Remove when sound.
      worldImpactBuilder
          .registerDynamicUse(DynamicUse(selector, null, const []));
    }
    for (InterfaceType instantiatedType in instantiatedTypes) {
      worldImpactBuilder
          .registerTypeUse(TypeUse.instantiation(instantiatedType));
    }
    for (ClassEntity cls in instantiatedClasses) {
      worldImpactBuilder.registerTypeUse(
          TypeUse.instantiation(elementEnvironment.getRawType(cls)));
    }
    for (ClassEntity cls in globalClasses) {
      worldImpactBuilder.registerTypeUse(
          TypeUse.instantiation(elementEnvironment.getRawType(cls)));
    }
    for (BackendImpact otherImpact in otherImpacts) {
      otherImpact.registerImpact(worldImpactBuilder, elementEnvironment);
    }
  }
}

/// The JavaScript backend dependencies for various features.
class BackendImpacts {
  final CommonElements _commonElements;
  final CompilerOptions _options;

  BackendImpacts(this._commonElements, this._options);

  late final BackendImpact getRuntimeTypeArgument = BackendImpact(
    globalUses: [],
    otherImpacts: [newRtiImpact],
  );

  late final BackendImpact computeSignature = BackendImpact(
    globalUses: [
      _commonElements.setArrayType,
    ],
    otherImpacts: [listValues],
  );

  late final BackendImpact mainWithArguments = BackendImpact(
    globalUses: [_commonElements.convertMainArgumentList],
    instantiatedClasses: [
      _commonElements.jsArrayClass,
      _commonElements.jsStringClass
    ],
  );

  late final BackendImpact asyncBody = BackendImpact(
    staticUses: [
      _commonElements.asyncHelperAwait,
      _commonElements.asyncHelperReturn,
      _commonElements.asyncHelperRethrow,
      _commonElements.streamIteratorConstructor,
      _commonElements.wrapBody,
      _commonElements.asyncHelperStartSync
    ],
  );

  late final BackendImpact syncStarBody = BackendImpact(
    staticUses: [
      _commonElements.endOfIteration,
      _commonElements.yieldStar,
      _commonElements.syncStarUncaughtError,
    ],
  );

  late final BackendImpact asyncStarBody = BackendImpact(
    staticUses: [
      _commonElements.asyncStarHelper,
      _commonElements.streamOfController,
      _commonElements.yieldSingle,
      _commonElements.yieldStar,
      _commonElements.streamIteratorConstructor,
      _commonElements.wrapBody,
    ],
  );

  late final BackendImpact typeVariableBoundCheck = BackendImpact(
    staticUses: [
      _commonElements.checkTypeBound,
    ],
  );

  late final BackendImpact asCheck = BackendImpact(
    staticUses: [],
    otherImpacts: [
      newRtiImpact,
    ],
  );

  late final BackendImpact stringValues = BackendImpact(
    instantiatedClasses: [_commonElements.jsStringClass],
  );

  late final BackendImpact numValues = BackendImpact(
    instantiatedClasses: [
      _commonElements.jsIntClass,
      _commonElements.jsPositiveIntClass,
      _commonElements.jsUInt32Class,
      _commonElements.jsUInt31Class,
      _commonElements.jsNumberClass,
      _commonElements.jsNumNotIntClass,
    ],
  );

  BackendImpact get intValues => numValues;

  BackendImpact get doubleValues => numValues;

  late final BackendImpact boolValues = BackendImpact(
    instantiatedClasses: [_commonElements.jsBoolClass],
  );

  late final BackendImpact nullValue = BackendImpact(
    instantiatedClasses: [_commonElements.jsNullClass],
  );

  late final BackendImpact listValues = BackendImpact(
    globalClasses: [
      _commonElements.jsArrayClass,
      _commonElements.jsMutableArrayClass,
      _commonElements.jsFixedArrayClass,
      _commonElements.jsExtendableArrayClass,
      _commonElements.jsUnmodifiableArrayClass
    ],
  );

  late final BackendImpact throwUnsupportedError = BackendImpact(
    staticUses: [_commonElements.throwUnsupportedError],
    otherImpacts: [
      // Also register the types of the arguments passed to this method.
      stringValues
    ],
  );

  late final BackendImpact superNoSuchMethod = BackendImpact(
    staticUses: [
      _commonElements.createInvocationMirror,
      _commonElements.objectNoSuchMethod
    ],
    otherImpacts: [
      _needsInt('Needed to encode the invocation kind of super.noSuchMethod.'),
      _needsList('Needed to encode the arguments of super.noSuchMethod.'),
      _needsString('Needed to encode the name of super.noSuchMethod.')
    ],
  );

  late final BackendImpact constantMapLiteral = BackendImpact(
    instantiatedClasses: [
      _commonElements.constantMapClass,
      _commonElements.constantStringMapClass,
      _commonElements.generalConstantMapClass,
    ],
  );

  late final BackendImpact constantSetLiteral = BackendImpact(
    instantiatedClasses: [
      _commonElements.constSetLiteralClass,
    ],
    otherImpacts: [constantMapLiteral],
  );

  late final BackendImpact constSymbol = BackendImpact(
    instantiatedClasses: [_commonElements.symbolImplementationClass],
    staticUses: [_commonElements.symbolConstructorTarget],
  );

  /// Helper for registering that `int` is needed.
  BackendImpact _needsInt(String reason) {
    // TODO(johnniwinther): Register [reason] for use in dump-info.
    return intValues;
  }

  /// Helper for registering that `List` is needed.
  BackendImpact _needsList(String reason) {
    // TODO(johnniwinther): Register [reason] for use in dump-info.
    return listValues;
  }

  /// Helper for registering that `String` is needed.
  BackendImpact _needsString(String reason) {
    // TODO(johnniwinther): Register [reason] for use in dump-info.
    return stringValues;
  }

  late final BackendImpact assertWithoutMessage = BackendImpact(
    staticUses: [_commonElements.assertHelper],
  );

  late final BackendImpact assertWithMessage = BackendImpact(
    staticUses: [_commonElements.assertTest, _commonElements.assertThrow],
  );

  late final BackendImpact asyncForIn = BackendImpact(
    staticUses: [_commonElements.streamIteratorConstructor],
  );

  late final BackendImpact stringInterpolation = BackendImpact(
    dynamicUses: [Selectors.toString_],
    staticUses: [_commonElements.stringInterpolationHelper],
    otherImpacts: [_needsString('Strings are created.')],
  );

  late final BackendImpact stringJuxtaposition =
      _needsString('String.concat is used.');

  BackendImpact get nullLiteral => nullValue;

  BackendImpact get boolLiteral => boolValues;

  BackendImpact get intLiteral => intValues;

  BackendImpact get doubleLiteral => doubleValues;

  BackendImpact get stringLiteral => stringValues;

  late final BackendImpact catchStatement = BackendImpact(
    staticUses: [_commonElements.exceptionUnwrapper],
    instantiatedClasses: [
      _commonElements.jsPlainJavaScriptObjectClass,
      _commonElements.jsUnknownJavaScriptObjectClass
    ],
  );

  late final BackendImpact throwExpression = BackendImpact(
    // We don't know ahead of time whether we will need the throw in a statement
    // context or an expression context, so we register both here, even though
    // we may not need the throwExpression helper.
    staticUses: [
      _commonElements.wrapExceptionHelper,
      _commonElements.throwExpressionHelper
    ],
  );

  late final BackendImpact lazyField = BackendImpact(
    staticUses: [
      _commonElements.cyclicThrowHelper,
      _commonElements.throwLateFieldADI,
    ],
  );

  late final BackendImpact typeLiteral = BackendImpact(
    instantiatedClasses: [_commonElements.typeLiteralClass],
    staticUses: [
      _commonElements.createRuntimeType,
      _commonElements.typeLiteralMaker,
    ],
  );

  late final BackendImpact stackTraceInCatch = BackendImpact(
    instantiatedClasses: [_commonElements.stackTraceHelperClass],
    staticUses: [_commonElements.traceFromException],
  );

  late final BackendImpact syncForIn = BackendImpact(
    // The SSA builder recognizes certain for-in loops and can generate
    // calls to throwConcurrentModificationError.
    staticUses: [_commonElements.checkConcurrentModificationError],
  );

  late final BackendImpact typeVariableExpression = BackendImpact(
    staticUses: [
      _commonElements.setArrayType,
      _commonElements.createRuntimeType
    ],
    otherImpacts: [
      listValues,
      getRuntimeTypeArgument,
      _needsInt('Needed for accessing a type variable literal on this.')
    ],
  );

  late final BackendImpact typeCheck =
      BackendImpact(otherImpacts: [boolValues, newRtiImpact]);

  late final BackendImpact genericTypeCheck = BackendImpact(
    staticUses: [
      // TODO(johnniwinther): Investigate why this is needed.
      _commonElements.setArrayType,
    ],
    otherImpacts: [
      listValues,
      getRuntimeTypeArgument,
      newRtiImpact,
    ],
  );

  late final BackendImpact genericIsCheck =
      BackendImpact(otherImpacts: [intValues, newRtiImpact]);

  late final BackendImpact typeVariableTypeCheck =
      BackendImpact(staticUses: [], otherImpacts: [newRtiImpact]);

  late final BackendImpact functionTypeCheck = BackendImpact(
    staticUses: [/*helpers.functionTypeTestMetaHelper*/],
    otherImpacts: [newRtiImpact],
  );

  late final BackendImpact futureOrTypeCheck = BackendImpact(
    staticUses: [],
    otherImpacts: [newRtiImpact],
  );

  late final BackendImpact nativeTypeCheck = BackendImpact(
    staticUses: [
      // We will need to add the "$is" and "$as" properties on the
      // JavaScript object prototype, so we make sure
      // [:defineProperty:] is compiled.
      _commonElements.defineProperty
    ],
    otherImpacts: [newRtiImpact],
  );

  late final BackendImpact closure = BackendImpact(
    instantiatedClasses: [_commonElements.functionClass],
  );

  late final BackendImpact interceptorUse = BackendImpact(
    staticUses: [_commonElements.getNativeInterceptorMethod],
    instantiatedClasses: [
      _commonElements.jsJavaScriptObjectClass,
      _commonElements.jsLegacyJavaScriptObjectClass,
      _commonElements.jsPlainJavaScriptObjectClass,
      _commonElements.jsJavaScriptFunctionClass
    ],
    features: EnumSet<BackendFeature>.fromValues([
      BackendFeature.needToInitializeDispatchProperty,
      BackendFeature.needToInitializeIsolateAffinityTag
    ], fixed: true),
  );

  late final BackendImpact allowInterop = BackendImpact(
    staticUses: [
      _commonElements.jsAllowInterop1!,
      _commonElements.jsAllowInterop2!,
    ],
    features: EnumSet<BackendFeature>.fromValues([
      BackendFeature.needToInitializeIsolateAffinityTag,
    ], fixed: true),
  );

  late final BackendImpact numClasses = BackendImpact(
    // The backend will try to optimize number operations and use the
    // `iae` helper directly.
    globalUses: [_commonElements.throwIllegalArgumentException],
  );

  late final BackendImpact listOrStringClasses = BackendImpact(
    // The backend will try to optimize array and string access and use the
    // `ioore` and `iae` _commonElements directly.
    globalUses: [
      _commonElements.throwIndexOutOfRangeException,
      _commonElements.throwIllegalArgumentException
    ],
  );

  late final BackendImpact functionClass = BackendImpact(
    globalClasses: [
      _commonElements.closureClass,
      _commonElements.closureClass0Args,
      _commonElements.closureClass2Args,
    ],
  );

  late final BackendImpact mapClass = BackendImpact(
    // The backend will use a literal list to initialize the entries of the map.
    globalClasses: [_commonElements.listClass, _commonElements.mapLiteralClass],
  );

  late final BackendImpact setClass = BackendImpact(
    globalClasses: [
      // The backend will use a literal list to initialize the entries of the
      // set.
      _commonElements.listClass,
      _commonElements.setLiteralClass,
    ],
  );

  late final BackendImpact boundClosureClass = BackendImpact(
    globalClasses: [_commonElements.boundClosureClass],
  );

  late final BackendImpact nativeOrExtendsClass = BackendImpact(
    globalUses: [_commonElements.getNativeInterceptorMethod],
    globalClasses: [
      _commonElements.jsInterceptorClass,
      _commonElements.jsJavaScriptObjectClass,
      _commonElements.jsLegacyJavaScriptObjectClass,
      _commonElements.jsPlainJavaScriptObjectClass,
      _commonElements.jsJavaScriptFunctionClass
    ],
  );

  late final BackendImpact mapLiteralClass = BackendImpact(
    globalUses: [
      _commonElements.mapLiteralConstructor,
      _commonElements.mapLiteralConstructorEmpty,
      _commonElements.mapLiteralUntypedMaker,
      _commonElements.mapLiteralUntypedEmptyMaker
    ],
  );

  late final BackendImpact setLiteralClass = BackendImpact(
    globalUses: [
      _commonElements.setLiteralConstructor,
      _commonElements.setLiteralConstructorEmpty,
      _commonElements.setLiteralUntypedMaker,
      _commonElements.setLiteralUntypedEmptyMaker,
    ],
  );

  late final BackendImpact closureClass = BackendImpact(
    globalUses: [_commonElements.closureFromTearOff],
  );

  late final BackendImpact listClasses = BackendImpact(
    // Literal lists can be translated into calls to these functions:
    globalUses: [
      _commonElements.jsArrayTypedConstructor,
      _commonElements.setArrayType,
    ],
  );

  late final BackendImpact jsIndexingBehavior = BackendImpact(
    // These two _commonElements are used by the emitter and the codegen.
    // Because we cannot enqueue elements at the time of emission,
    // we make sure they are always generated.
    globalUses: [_commonElements.isJsIndexable],
  );

  late final BackendImpact traceHelper = BackendImpact(
    globalUses: [_commonElements.traceHelper],
  );

  late final BackendImpact assertUnreachable = BackendImpact(
    globalUses: [_commonElements.assertUnreachableMethod],
  );

  late final BackendImpact runtimeTypeSupport = BackendImpact(
    globalClasses: [_commonElements.listClass],
    globalUses: [
      _commonElements.setArrayType,
    ],
    otherImpacts: [getRuntimeTypeArgument, computeSignature],
  );

  late final BackendImpact deferredLoading = BackendImpact(
    globalUses: [_commonElements.checkDeferredIsLoaded],
    // Also register the types of the arguments passed to this method.
    globalClasses: [_commonElements.stringClass],
  );

  late final BackendImpact noSuchMethodSupport = BackendImpact(
    globalUses: [
      _commonElements.createInvocationMirror,
      _commonElements.createUnmangledInvocationMirror
    ],
    dynamicUses: [Selectors.noSuchMethod_],
  );

  /// Backend impact for accessing a `loadLibrary` function on a deferred
  /// prefix.
  late final BackendImpact loadLibrary = BackendImpact(
    globalUses: [
      _commonElements.loadDeferredLibrary,
    ],
  );

  /// Backend impact for performing member closurization.
  late final BackendImpact memberClosure =
      BackendImpact(globalClasses: [_commonElements.boundClosureClass]);

  /// Backend impact for performing closurization of a top-level or static
  /// function.
  late final BackendImpact staticClosure =
      BackendImpact(globalClasses: [_commonElements.closureClass]);

  final Map<int, BackendImpact> _genericInstantiation = {};

  BackendImpact getGenericInstantiation(int typeArgumentCount) =>
      _genericInstantiation[typeArgumentCount] ??= BackendImpact(
        staticUses: [
          _commonElements.getInstantiateFunction(typeArgumentCount),
          _commonElements.instantiatedGenericFunctionTypeNewRti,
          _commonElements.closureFunctionType,
        ],
        instantiatedClasses: [
          _commonElements.getInstantiationClass(typeArgumentCount),
        ],
      );

  // TODO(sra): Split into refined impacts.
  late final BackendImpact newRtiImpact = BackendImpact(
    staticUses: [
      _commonElements.findType,
      _commonElements.instanceType,
      _commonElements.arrayInstanceType,
      _commonElements.simpleInstanceType,
      _commonElements.rtiEvalMethod,
      _commonElements.rtiBindMethod,
      _commonElements.installSpecializedIsTest,
      _commonElements.generalIsTestImplementation,
      _commonElements.generalAsCheckImplementation,
      _commonElements.installSpecializedAsCheck,
      _commonElements.generalNullableIsTestImplementation,
      _commonElements.generalNullableAsCheckImplementation,
      // Specialized checks.
      _commonElements.specializedIsBool,
      _commonElements.specializedAsBool,
      _commonElements.specializedAsBoolLegacy,
      _commonElements.specializedAsBoolNullable,
      // no specializedIsDouble.
      _commonElements.specializedAsDouble,
      _commonElements.specializedAsDoubleLegacy,
      _commonElements.specializedAsDoubleNullable,
      _commonElements.specializedIsInt,
      _commonElements.specializedAsInt,
      _commonElements.specializedAsIntLegacy,
      _commonElements.specializedAsIntNullable,
      _commonElements.specializedIsNum,
      _commonElements.specializedAsNum,
      _commonElements.specializedAsNumLegacy,
      _commonElements.specializedAsNumNullable,
      _commonElements.specializedIsString,
      _commonElements.specializedAsString,
      _commonElements.specializedAsStringLegacy,
      _commonElements.specializedAsStringNullable,
      _commonElements.specializedIsTop,
      _commonElements.specializedAsTop,
      _commonElements.specializedIsObject,
      _commonElements.specializedAsObject,
    ],
    globalClasses: [
      _commonElements.closureClass, // instanceOrFunctionType uses this.
    ],
  );

  // TODO(fishythefish): Split into refined impacts.
  late final BackendImpact rtiAddRules = BackendImpact(
    globalUses: [
      _commonElements.rtiAddRulesMethod,
      _commonElements.rtiAddErasedTypesMethod,
      if (_options.enableVariance)
        _commonElements.rtiAddTypeParameterVariancesMethod,
    ],
    otherImpacts: [_needsString('Needed to encode the new RTI ruleset.')],
  );

  late final BackendImpact lateFieldReadCheck = BackendImpact(
    globalUses: [
      _commonElements.throwUnnamedLateFieldNI,
      _commonElements.throwLateFieldNI,
    ],
  );

  late final BackendImpact lateFieldWriteOnceCheck = BackendImpact(
    globalUses: [
      _commonElements.throwUnnamedLateFieldAI,
      _commonElements.throwLateFieldAI,
    ],
  );

  late final BackendImpact lateFieldInitializeOnceCheck = BackendImpact(
    globalUses: [
      _commonElements.throwUnnamedLateFieldADI,
      _commonElements.throwLateFieldADI,
    ],
  );
}
