// 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.jsAllowInterop!,
    ],
    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,
    ],
  );

  late final BackendImpact recordInstantiation = BackendImpact(
    globalUses: [
      _commonElements.recordImpactModel,
    ],
  );
}
