// 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.

import '../common.dart';
import '../common/elements.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
import '../ir/runtime_type_analysis.dart';
import '../kernel/kernel_strategy_migrated.dart'
    show KernelFrontendStrategyForBackendUsage;
import '../serialization/serialization.dart';
import '../universe/feature.dart';
import '../util/util.dart' show Setlet;
import 'backend_impact.dart';

abstract class BackendUsage {
  /// Deserializes a [BackendUsage] object from [source].
  factory BackendUsage.readFromDataSource(DataSourceReader source) =
      BackendUsageImpl.readFromDataSource;

  /// Serializes this [BackendUsage] to [sink].
  void writeToDataSink(DataSinkWriter sink);

  abstract bool needToInitializeIsolateAffinityTag;
  abstract bool needToInitializeDispatchProperty;

  /// Returns `true` if [element] is a function called by the backend.
  bool isFunctionUsedByBackend(FunctionEntity element);

  /// Returns `true` if [element] is an instance field of a class instantiated
  /// by the backend.
  bool isFieldUsedByBackend(FieldEntity element);

  Iterable<FunctionEntity> get globalFunctionDependencies;

  Iterable<ClassEntity> get globalClassDependencies;

  Iterable<ClassEntity> get helperClassesUsed;

  Iterable<RuntimeTypeUse> get runtimeTypeUses;

  /// `true` if a core-library function requires the preamble file to function.
  bool get requiresPreamble;

  /// `true` of `Object.runtimeType` is used.
  bool get isRuntimeTypeUsed;

  /// `true` if `Function.apply` is used.
  bool get isFunctionApplyUsed;

  /// `true` if 'dart:mirrors' features are used.
  bool get isMirrorsUsed;

  /// `true` if startup timestamps are used.
  bool get requiresStartupMetrics;

  /// `true` if `noSuchMethod` is used.
  bool get isNoSuchMethodUsed;

  /// `true` if the `dart:html` is loaded.
  // TODO(johnniwinther): This is always `true` with the CFE.
  bool get isHtmlLoaded;
}

abstract class BackendUsageBuilder {
  /// The backend must *always* call this method when enqueuing an function
  /// element. Calls done by the backend are not seen by global
  /// optimizations, so they would make these optimizations unsound.
  /// Therefore we need to collect the list of methods the backend may
  /// call.
  // TODO(johnniwinther): Replace this with a more precise modelling; type
  // inference of parameters of these functions is disabled.
  void registerBackendFunctionUse(FunctionEntity element);

  /// The backend must *always* call this method when instantiating a class.
  /// Instantiations done by the backend are not seen by global optimizations,
  /// so they would make these optimizations unsound. Therefore we need to
  /// collect the list of classes the backend may instantiate.
  // TODO(johnniwinther): Replace this with a more precise modelling; type
  // inference of the instance fields of these classes is disabled.
  void registerBackendClassUse(ClassEntity element);

  void registerGlobalFunctionDependency(FunctionEntity element);
  void registerGlobalClassDependency(ClassEntity element);

  /// Collect backend use from [backendImpact].
  void processBackendImpact(BackendImpact backendImpact);

  void registerUsedMember(MemberEntity member);

  /// Register use of `runtimeType`.
  void registerRuntimeTypeUse(RuntimeTypeUse runtimeTypeUse);

  /// `true` if `Function.apply` is used.
  abstract bool isFunctionApplyUsed;

  /// `true` if `noSuchMethod` is used.
  abstract bool isNoSuchMethodUsed;

  /// Register that `dart:html` is loaded.
  void registerHtmlIsLoaded();

  BackendUsage close();
}

class BackendUsageBuilderImpl implements BackendUsageBuilder {
  final KernelFrontendStrategyForBackendUsage _frontendStrategy;
  // TODO(johnniwinther): Remove the need for these.
  Setlet<FunctionEntity>? _globalFunctionDependencies;
  Setlet<ClassEntity>? _globalClassDependencies;

  /// List of methods that the backend may use.
  final Set<FunctionEntity> _helperFunctionsUsed = {};

  /// List of classes that the backend may use.
  final Set<ClassEntity> _helperClassesUsed = {};

  final Set<RuntimeTypeUse> _runtimeTypeUses = {};

  bool _needToInitializeIsolateAffinityTag = false;
  bool _needToInitializeDispatchProperty = false;

  /// `true` if a core-library function requires the preamble file to function.
  bool requiresPreamble = false;

  /// `true` if a core-library function accesses startup timestamps.
  bool requiresStartupMetrics = false;

  @override
  bool isFunctionApplyUsed = false;

  /// `true` if 'dart:mirrors' features are used.
  bool isMirrorsUsed = false;

  @override
  bool isNoSuchMethodUsed = false;

  bool isHtmlLoaded = false;

  BackendUsageBuilderImpl(this._frontendStrategy);

  KCommonElements get _commonElements => _frontendStrategy.commonElements;

  @override
  void registerBackendFunctionUse(FunctionEntity element) {
    assert(_isValidBackendUse(element, element.library),
        failedAt(element, "Backend use of $element is not allowed."));
    _helperFunctionsUsed.add(element);
  }

  @override
  void registerBackendClassUse(ClassEntity element) {
    assert(_isValidBackendUse(element, element.library),
        failedAt(element, "Backend use of $element is not allowed."));
    _helperClassesUsed.add(element);
  }

  bool _isValidBackendUse(Entity element, LibraryEntity library) {
    if (_isValidEntity(element)) return true;
    SourceSpan span = _frontendStrategy.spanFromSpannable(element, element);
    if (library.canonicalUri.isScheme('dart') &&
        (span.uri.path.contains('_internal/js_runtime/lib') ||
            span.uri.path.contains('_internal/js_shared/lib'))) {
      // TODO(johnniwinther): We should be more precise about these.
      return true;
    } else {
      return false;
    }
  }

  bool _isValidEntity(Entity element) {
    if (element is ConstructorEntity &&
        (element == _commonElements.streamIteratorConstructor ||
            _commonElements.isSymbolConstructor(element))) {
      // TODO(johnniwinther): These are valid but we could be more precise.
      return true;
    } else if (element == _commonElements.symbolImplementationClass ||
        element == _commonElements.objectNoSuchMethod) {
      // TODO(johnniwinther): These are valid but we could be more precise.
      return true;
    } else if (element == _commonElements.listClass ||
        element == _commonElements.mapLiteralClass ||
        element == _commonElements.setLiteralClass ||
        element == _commonElements.unmodifiableSetClass ||
        element == _commonElements.functionClass ||
        element == _commonElements.stringClass) {
      // TODO(johnniwinther): Avoid these.
      return true;
    }
    return false;
  }

  void _processBackendStaticUse(FunctionEntity element,
      {bool isGlobal = false}) {
    registerBackendFunctionUse(element);
    if (isGlobal) {
      registerGlobalFunctionDependency(element);
    }
  }

  void _processBackendInstantiation(ClassEntity cls, {bool isGlobal = false}) {
    registerBackendClassUse(cls);
    if (isGlobal) {
      registerGlobalClassDependency(cls);
    }
  }

  @override
  void processBackendImpact(BackendImpact backendImpact) {
    for (FunctionEntity staticUse in backendImpact.staticUses) {
      assert((staticUse as dynamic) != null); // TODO(48820): Remove when sound.
      _processBackendStaticUse(staticUse);
    }
    for (FunctionEntity staticUse in backendImpact.globalUses) {
      assert((staticUse as dynamic) != null); // TODO(48820): Remove when sound.
      _processBackendStaticUse(staticUse, isGlobal: true);
    }
    for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) {
      registerBackendClassUse(instantiatedType.element);
    }
    for (ClassEntity cls in backendImpact.instantiatedClasses) {
      _processBackendInstantiation(cls);
    }
    for (ClassEntity cls in backendImpact.globalClasses) {
      _processBackendInstantiation(cls, isGlobal: true);
    }
    for (BackendImpact otherImpact in backendImpact.otherImpacts) {
      processBackendImpact(otherImpact);
    }
    for (BackendFeature feature in backendImpact.features) {
      switch (feature) {
        case BackendFeature.needToInitializeDispatchProperty:
          _needToInitializeDispatchProperty = true;
          break;
        case BackendFeature.needToInitializeIsolateAffinityTag:
          _needToInitializeIsolateAffinityTag = true;
          break;
      }
    }
  }

  @override
  void registerUsedMember(MemberEntity member) {
    if (member == _commonElements.getIsolateAffinityTagMarker) {
      _needToInitializeIsolateAffinityTag = true;
    } else if (member == _commonElements.requiresPreambleMarker) {
      requiresPreamble = true;
    } else if (_commonElements.isFunctionApplyMethod(member)) {
      isFunctionApplyUsed = true;
    } else if (member.library == _commonElements.mirrorsLibrary) {
      isMirrorsUsed = true;
    } else if (member == _commonElements.rawStartupMetrics) {
      requiresStartupMetrics = true;
    }
  }

  @override
  void registerGlobalFunctionDependency(FunctionEntity element) {
    assert((element as dynamic) != null); // TODO(48820): Remove when sound.
    _globalFunctionDependencies ??= Setlet();
    _globalFunctionDependencies!.add(element);
  }

  @override
  void registerGlobalClassDependency(ClassEntity element) {
    assert((element as dynamic) != null); // TODO(48820): Remove when sound.
    _globalClassDependencies ??= Setlet();
    _globalClassDependencies!.add(element);
  }

  @override
  void registerRuntimeTypeUse(RuntimeTypeUse runtimeTypeUse) {
    _runtimeTypeUses.add(runtimeTypeUse);
  }

  @override
  void registerHtmlIsLoaded() {
    isHtmlLoaded = true;
  }

  @override
  BackendUsage close() {
    return BackendUsageImpl(
        globalFunctionDependencies: _globalFunctionDependencies,
        globalClassDependencies: _globalClassDependencies,
        helperFunctionsUsed: _helperFunctionsUsed,
        helperClassesUsed: _helperClassesUsed,
        needToInitializeIsolateAffinityTag: _needToInitializeIsolateAffinityTag,
        needToInitializeDispatchProperty: _needToInitializeDispatchProperty,
        requiresPreamble: requiresPreamble,
        requiresStartupMetrics: requiresStartupMetrics,
        runtimeTypeUses: _runtimeTypeUses,
        isFunctionApplyUsed: isFunctionApplyUsed,
        isMirrorsUsed: isMirrorsUsed,
        isNoSuchMethodUsed: isNoSuchMethodUsed,
        isHtmlLoaded: isHtmlLoaded);
  }
}

class BackendUsageImpl implements BackendUsage {
  /// Tag used for identifying serialized [BackendUsage] objects in a
  /// debugging data stream.
  static const String tag = 'backend-usage';

  // TODO(johnniwinther): Remove the need for these.
  final Set<FunctionEntity>? _globalFunctionDependencies;
  final Set<ClassEntity>? _globalClassDependencies;

  /// Set of functions called by the backend.
  final Set<FunctionEntity> _helperFunctionsUsed;

  /// Set of classes instantiated by the backend.
  final Set<ClassEntity> _helperClassesUsed;

  final Set<RuntimeTypeUse> _runtimeTypeUses;

  @override
  bool needToInitializeIsolateAffinityTag;
  @override
  bool needToInitializeDispatchProperty;

  @override
  final bool requiresPreamble;

  @override
  final bool requiresStartupMetrics;

  @override
  final bool isFunctionApplyUsed;

  @override
  final bool isMirrorsUsed;

  @override
  final bool isNoSuchMethodUsed;

  @override
  final bool isHtmlLoaded;

  BackendUsageImpl(
      {required Set<FunctionEntity>? globalFunctionDependencies,
      required Set<ClassEntity>? globalClassDependencies,
      required Set<FunctionEntity> helperFunctionsUsed,
      required Set<ClassEntity> helperClassesUsed,
      required this.needToInitializeIsolateAffinityTag,
      required this.needToInitializeDispatchProperty,
      required this.requiresPreamble,
      required this.requiresStartupMetrics,
      required Set<RuntimeTypeUse> runtimeTypeUses,
      required this.isFunctionApplyUsed,
      required this.isMirrorsUsed,
      required this.isNoSuchMethodUsed,
      required this.isHtmlLoaded})
      : this._globalFunctionDependencies = globalFunctionDependencies,
        this._globalClassDependencies = globalClassDependencies,
        this._helperFunctionsUsed = helperFunctionsUsed,
        this._helperClassesUsed = helperClassesUsed,
        this._runtimeTypeUses = runtimeTypeUses;

  factory BackendUsageImpl.readFromDataSource(DataSourceReader source) {
    source.begin(tag);
    Set<FunctionEntity> globalFunctionDependencies =
        source.readMembers<FunctionEntity>().toSet();
    Set<ClassEntity> globalClassDependencies = source.readClasses().toSet();
    Set<FunctionEntity> helperFunctionsUsed =
        source.readMembers<FunctionEntity>().toSet();
    Set<ClassEntity> helperClassesUsed = source.readClasses().toSet();
    Set<RuntimeTypeUse> runtimeTypeUses = source.readList(() {
      RuntimeTypeUseKind kind = source.readEnum(RuntimeTypeUseKind.values);
      DartType receiverType = source.readDartType();
      DartType? argumentType = source.readDartTypeOrNull();
      return RuntimeTypeUse(kind, receiverType, argumentType);
    }).toSet();
    bool needToInitializeIsolateAffinityTag = source.readBool();
    bool needToInitializeDispatchProperty = source.readBool();
    bool requiresPreamble = source.readBool();
    bool requiresStartupMetrics = source.readBool();
    bool isFunctionApplyUsed = source.readBool();
    bool isMirrorsUsed = source.readBool();
    bool isNoSuchMethodUsed = source.readBool();
    bool isHtmlLoaded = source.readBool();
    source.end(tag);
    return BackendUsageImpl(
        globalFunctionDependencies: globalFunctionDependencies,
        globalClassDependencies: globalClassDependencies,
        helperFunctionsUsed: helperFunctionsUsed,
        helperClassesUsed: helperClassesUsed,
        runtimeTypeUses: runtimeTypeUses,
        needToInitializeIsolateAffinityTag: needToInitializeIsolateAffinityTag,
        needToInitializeDispatchProperty: needToInitializeDispatchProperty,
        requiresPreamble: requiresPreamble,
        requiresStartupMetrics: requiresStartupMetrics,
        isFunctionApplyUsed: isFunctionApplyUsed,
        isMirrorsUsed: isMirrorsUsed,
        isNoSuchMethodUsed: isNoSuchMethodUsed,
        isHtmlLoaded: isHtmlLoaded);
  }

  @override
  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMembers(_globalFunctionDependencies, allowNull: true);
    sink.writeClasses(_globalClassDependencies, allowNull: true);
    sink.writeMembers(_helperFunctionsUsed);
    sink.writeClasses(_helperClassesUsed);
    sink.writeList(runtimeTypeUses, (RuntimeTypeUse runtimeTypeUse) {
      sink.writeEnum(runtimeTypeUse.kind);
      sink.writeDartType(runtimeTypeUse.receiverType);
      sink.writeDartTypeOrNull(runtimeTypeUse.argumentType);
    });
    sink.writeBool(needToInitializeIsolateAffinityTag);
    sink.writeBool(needToInitializeDispatchProperty);
    sink.writeBool(requiresPreamble);
    sink.writeBool(requiresStartupMetrics);
    sink.writeBool(isFunctionApplyUsed);
    sink.writeBool(isMirrorsUsed);
    sink.writeBool(isNoSuchMethodUsed);
    sink.writeBool(isHtmlLoaded);
    sink.end(tag);
  }

  @override
  bool isFunctionUsedByBackend(FunctionEntity element) {
    return _helperFunctionsUsed.contains(element);
  }

  @override
  bool isFieldUsedByBackend(FieldEntity element) {
    return _helperClassesUsed.contains(element.enclosingClass);
  }

  @override
  Iterable<FunctionEntity> get globalFunctionDependencies =>
      _globalFunctionDependencies ?? const [];

  @override
  Iterable<ClassEntity> get globalClassDependencies =>
      _globalClassDependencies ?? const [];

  Iterable<FunctionEntity> get helperFunctionsUsed => _helperFunctionsUsed;

  @override
  Iterable<ClassEntity> get helperClassesUsed => _helperClassesUsed;

  @override
  bool get isRuntimeTypeUsed => _runtimeTypeUses.isNotEmpty;

  @override
  Iterable<RuntimeTypeUse> get runtimeTypeUses => _runtimeTypeUses;
}
