// 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 'package:kernel/ast.dart' as ir;

import '../common.dart';
import '../constants/values.dart';
import '../elements/entities.dart';
import '../elements/entity_utils.dart';
import '../elements/types.dart';
import '../ir/scope_visitor.dart';
import '../js_model/elements.dart' show JClass, JConstructor, JField;
import '../js_model/js_to_frontend_map.dart' show JsToFrontendMap;
import '../kernel/element_map.dart' show KernelToElementMap;
import '../kernel/kernel_world.dart';
import '../options.dart';
import '../serialization/serialization.dart';
import '../universe/member_usage.dart';

/// AllocatorAnalysis
///
/// Analysis to determine features of the allocator functions. The allocator
/// function takes parameters for each field initializer and initializes the
/// fields.  Parameters may be omitted if the initializer is always the same
/// constant value.  How the allocator is emitted will determine what kind of
/// constants can be handled.  The initial implementation only permits `null`.

// TODO(sra): Analysis to determine field order. Current field order is
// essentially declaration order, subclass first. We can reorder fields so that
// fields initialized with the same constant are together to allow chained
// initialization. Fields of a class and superclass can be reordered to allow
// chaining, e.g.
//
//     this.x = this.z = null;
//
class KFieldAnalysis {
  final KernelToElementMap _elementMap;

  final Map<JClass, ClassData> _classData = {};
  final Map<JField, StaticFieldData> _staticFieldData = {};

  KFieldAnalysis(this._elementMap);

  // Register class during resolution. Use simple syntactic analysis to find
  // null-initialized fields.
  void registerInstantiatedClass(JClass class_) {
    ir.Class classNode = _elementMap.getClassNode(class_);

    List<JConstructor> constructors = [];
    Map<JField, AllocatorData> fieldData = {};
    for (ir.Field field in classNode.fields) {
      if (!field.isInstanceMember) continue;

      FieldEntity fieldElement = _elementMap.getField(field);
      ir.Expression? expression = field.initializer;
      ConstantValue? value;
      if (expression is ir.StaticInvocation &&
          identical(
            expression.target,
            _elementMap.coreTypes.createSentinelMethod,
          )) {
        value = LateSentinelConstantValue();
      } else {
        value = _elementMap.getConstantValue(
          expression,
          requireConstant: false,
          implicitNull: true,
        );
      }
      if (value != null && value.isConstant) {
        fieldData[fieldElement as JField] = AllocatorData(value);
      }
    }

    for (ir.Constructor constructor in classNode.constructors) {
      JConstructor constructorElement =
          _elementMap.getConstructor(constructor) as JConstructor;
      constructors.add(constructorElement);
      for (ir.Initializer initializer in constructor.initializers) {
        if (initializer is ir.FieldInitializer) {
          AllocatorData? data =
              fieldData[_elementMap.getField(initializer.field) as JField];
          if (data == null) {
            // TODO(johnniwinther): Support initializers with side-effects?

            // The field has a non-constant initializer.
            continue;
          }

          Initializer initializerValue = const Initializer.complex();
          ir.Expression value = initializer.value;
          ConstantValue? constantValue = _elementMap.getConstantValue(
            value,
            requireConstant: false,
            implicitNull: true,
          );
          if (constantValue != null && constantValue.isConstant) {
            initializerValue = Initializer.direct(constantValue);
          } else if (value is ir.VariableGet) {
            ir.VariableDeclaration parameter = value.variable;
            int position = constructor.function.positionalParameters.indexOf(
              parameter,
            );
            if (position != -1) {
              if (position >= constructor.function.requiredParameterCount) {
                constantValue = _elementMap.getConstantValue(
                  parameter.initializer,
                  requireConstant: false,
                  implicitNull: true,
                );
                if (constantValue != null && constantValue.isConstant) {
                  initializerValue = Initializer.positional(
                    position,
                    constantValue,
                  );
                }
              }
            } else {
              position = constructor.function.namedParameters.indexOf(
                parameter,
              );
              if (position != -1) {
                constantValue = _elementMap.getConstantValue(
                  parameter.initializer,
                  requireConstant: false,
                  implicitNull: true,
                );
                if (constantValue != null && constantValue.isConstant) {
                  initializerValue = Initializer.named(
                    parameter.name,
                    constantValue,
                  );
                }
              }
            }
          }
          data.initializers[constructorElement] = initializerValue;
        }
      }
    }
    _classData[class_] = ClassData(constructors, fieldData);
  }

  void registerStaticField(JField field, EvaluationComplexity complexity) {
    ir.Field node = _elementMap.getMemberNode(field) as ir.Field;
    ir.Expression? expression = node.initializer;
    ConstantValue? value;
    if (expression is ir.StaticInvocation &&
        identical(
          expression.target,
          _elementMap.coreTypes.createSentinelMethod,
        )) {
      value = LateSentinelConstantValue();
    } else {
      value = _elementMap.getConstantValue(
        expression,
        requireConstant: node.isConst,
        implicitNull: true,
      );
    }
    if (value != null && !value.isConstant) {
      value = null;
    }
    // TODO(johnniwinther): Remove evaluation of constant when [complexity]
    // holds the constant literal from CFE.
    _staticFieldData[field] = StaticFieldData(value, complexity);
  }

  AllocatorData? getAllocatorDataForTesting(JField field) {
    return _classData[field.enclosingClass!]!.fieldData[field];
  }

  StaticFieldData? getStaticFieldDataForTesting(JField field) {
    return _staticFieldData[field];
  }
}

class ClassData {
  final List<JConstructor> constructors;
  final Map<JField, AllocatorData> fieldData;

  ClassData(this.constructors, this.fieldData);
}

class StaticFieldData {
  final ConstantValue? initialValue;
  final EvaluationComplexity complexity;

  StaticFieldData(this.initialValue, this.complexity);

  bool get hasDependencies => complexity.fields != null;
}

class AllocatorData {
  final ConstantValue? initialValue;
  final Map<JConstructor, Initializer> initializers = {};

  AllocatorData(this.initialValue);

  @override
  String toString() =>
      'AllocatorData(initialValue=${initialValue?.toStructuredText(null)},'
      'initializers=$initializers)';
}

enum InitializerKind { direct, positional, named, complex }

class Initializer {
  final InitializerKind kind;
  final int? index;
  final String? name;
  final ConstantValue? value;

  Initializer.direct(this.value)
    : kind = InitializerKind.direct,
      index = null,
      name = null;

  Initializer.positional(this.index, this.value)
    : kind = InitializerKind.positional,
      name = null;

  Initializer.named(this.name, this.value)
    : kind = InitializerKind.named,
      index = null;

  const Initializer.complex()
    : kind = InitializerKind.complex,
      index = null,
      name = null,
      value = null;

  String shortText(DartTypes? dartTypes) {
    switch (kind) {
      case InitializerKind.direct:
        return value!.toStructuredText(dartTypes);
      case InitializerKind.positional:
        return '$index:${value!.toStructuredText(dartTypes)}';
      case InitializerKind.named:
        return '$name:${value!.toStructuredText(dartTypes)}';
      case InitializerKind.complex:
        return '?';
    }
  }

  @override
  String toString() => shortText(null);
}

class JFieldAnalysis {
  /// Tag used for identifying serialized [JFieldAnalysis] objects in a
  /// debugging data stream.
  static const String tag = 'field-analysis';

  // --csp and --fast-startup have different constraints to the generated code.

  final Map<FieldEntity, FieldAnalysisData> _fieldData;

  JFieldAnalysis._(this._fieldData);

  /// Deserializes a [JFieldAnalysis] object from [source].
  factory JFieldAnalysis.readFromDataSource(
    DataSourceReader source,
    CompilerOptions options,
  ) {
    source.begin(tag);
    Map<FieldEntity, FieldAnalysisData> fieldData = source.readMemberMap(
      (MemberEntity member) => FieldAnalysisData.fromDataSource(source),
    );
    source.end(tag);
    return JFieldAnalysis._(fieldData);
  }

  /// Serializes this [JFieldAnalysis] to [sink].
  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMemberMap(
      _fieldData,
      (MemberEntity member, FieldAnalysisData data) =>
          data.writeToDataSink(sink),
    );
    sink.end(tag);
  }

  factory JFieldAnalysis.from(
    KClosedWorld closedWorld,
    JsToFrontendMap map,
    CompilerOptions options,
  ) {
    Map<FieldEntity, FieldAnalysisData> fieldData = {};

    bool canBeElided(FieldEntity field) {
      return !closedWorld.annotationsData.hasNoElision(field) &&
          !closedWorld.nativeData.isNativeMember(field);
    }

    closedWorld.fieldAnalysis._classData.forEach((
      ClassEntity cls,
      ClassData classData,
    ) {
      classData.fieldData.forEach((JField kField, AllocatorData data) {
        JField? jField = map.toBackendMember(kField) as JField?;
        if (jField == null) {
          return;
        }

        // TODO(johnniwinther): Should elided static fields be removed from the
        // J model? Static setters might still assign to them.

        MemberUsage memberUsage = closedWorld.liveMemberUsage[kField]!;
        if (!memberUsage.hasRead) {
          if (canBeElided(kField)) {
            fieldData[jField] = const FieldAnalysisData(isElided: true);
          }
          // TODO(sra): Because we skip the logic below for fields annotated
          // with `@pragma('dart2js:noElision')`, fields retained due to the
          // pragma are not deduced to be `isInitializedInAllocator` even when
          // they could be.
        } else {
          if (data.initialValue != null) {
            ConstantValue? initialValue;
            bool isTooComplex = false;

            void includeInitialValue(ConstantValue? value) {
              if (isTooComplex) return;
              if (initialValue == null) {
                initialValue = value;
              } else if (initialValue != value) {
                initialValue = null;
                isTooComplex = true;
              }
            }

            memberUsage.initialConstants!.forEach(includeInitialValue);

            bool inAllConstructors = true;
            for (JConstructor constructor in classData.constructors) {
              if (isTooComplex) {
                break;
              }

              MemberUsage? constructorUsage =
                  closedWorld.liveMemberUsage[constructor];
              if (constructorUsage == null) {
                // This constructor isn't called.
                continue;
              }
              ParameterStructure? invokedParameters =
                  closedWorld.annotationsData.hasNoElision(constructor)
                  ? constructor.parameterStructure
                  : constructorUsage.invokedParameters;

              Initializer? initializer = data.initializers[constructor];
              if (initializer == null) {
                inAllConstructors = false;
              } else {
                switch (initializer.kind) {
                  case InitializerKind.direct:
                    includeInitialValue(initializer.value);
                    break;
                  case InitializerKind.positional:
                    if (initializer.index! >=
                        invokedParameters!.positionalParameters) {
                      includeInitialValue(initializer.value);
                    } else {
                      isTooComplex = true;
                    }
                    break;
                  case InitializerKind.named:
                    if (!invokedParameters!.namedParameters.contains(
                      initializer.name,
                    )) {
                      includeInitialValue(initializer.value);
                    } else {
                      isTooComplex = true;
                    }
                    break;
                  case InitializerKind.complex:
                    isTooComplex = true;
                    break;
                }
              }
            }
            if (!inAllConstructors) {
              includeInitialValue(data.initialValue);
            }
            if (!isTooComplex && initialValue != null) {
              ConstantValue value = map.toBackendConstant(initialValue!)!;
              bool isEffectivelyConstant = false;
              bool isAssignedOnce = false;
              bool isLateBackingField = false;
              bool isInitializedInAllocator = false;
              if (!memberUsage.hasWrite && canBeElided(kField)) {
                isEffectivelyConstant = true;
              } else if (value is PrimitiveConstantValue ||
                  value is LateSentinelConstantValue) {
                // TODO(johnniwinther,sra): Support non-primitive constants in
                // allocators when it does cause allocators to deoptimized
                // because of deferred loading.
                isInitializedInAllocator = true;
                isLateBackingField = closedWorld.elementEnvironment
                    .isLateBackingField(kField);
                isAssignedOnce = closedWorld.elementEnvironment
                    .isLateFinalBackingField(kField);
              }
              fieldData[jField] = FieldAnalysisData(
                initialValue: value,
                isEffectivelyFinal: isEffectivelyConstant,
                isElided: isEffectivelyConstant,
                isAssignedOnce: isAssignedOnce,
                isLateBackingField: isLateBackingField,
                isInitializedInAllocator: isInitializedInAllocator,
              );
            }
          }
        }
      });
    });

    List<JField> independentFields = [];
    List<JField> dependentFields = [];

    closedWorld.liveMemberUsage.forEach((
      MemberEntity member,
      MemberUsage memberUsage,
    ) {
      if (member is FieldEntity && !member.isInstanceMember) {
        StaticFieldData staticFieldData =
            closedWorld.fieldAnalysis._staticFieldData[member as JField]!;
        if (staticFieldData.hasDependencies) {
          dependentFields.add(member);
        } else {
          independentFields.add(member);
        }
      }
    });

    // Fields already processed.
    Set<JField> processedFields = {};

    // Fields currently being processed. Use for detecting cyclic dependencies.
    Set<JField> currentFields = {};

    // Index ascribed to eager fields that depend on other fields. This is
    // used to sort the field in emission to ensure that used fields have been
    // initialized when read.
    int eagerCreationIndex = 0;

    /// Computes the [FieldAnalysisData] for the JField corresponding to
    /// [kField].
    ///
    /// If the data is currently been computed, that is, [kField] has a
    /// cyclic dependency, `null` is returned.
    FieldAnalysisData? processField(JField kField) {
      JField? jField = map.toBackendMember(kField) as JField?;
      // TODO(johnniwinther): Can we assert that [jField] exists?
      if (jField == null) return null;

      FieldAnalysisData? data = fieldData[jField];
      if (processedFields.contains(kField)) {
        // We only store data for non-trivial [FieldAnalysisData].
        return data ?? const FieldAnalysisData();
      }
      if (currentFields.contains(kField)) {
        // Cyclic dependency.
        return null;
      }
      currentFields.add(kField);
      MemberUsage memberUsage = closedWorld.liveMemberUsage[kField]!;
      if (!memberUsage.hasRead && canBeElided(kField)) {
        data = fieldData[jField] = const FieldAnalysisData(isElided: true);
      } else {
        bool isEffectivelyFinal = !memberUsage.hasWrite;
        StaticFieldData staticFieldData =
            closedWorld.fieldAnalysis._staticFieldData[kField]!;
        ConstantValue? value = map.toBackendConstant(
          staticFieldData.initialValue,
          allowNull: true,
        );

        // If the field is effectively final with a constant initializer we
        // elide the field, if allowed, because it is effectively constant.
        bool isElided =
            isEffectivelyFinal && value != null && canBeElided(kField);

        bool isEager;

        // If the field is eager and dependent on other eager fields,
        // [eagerFieldDependencies] holds these fields and [creationIndex] is
        // given the creation order index used to ensure that all dependencies
        // have been assigned their values before this field is initialized.
        //
        // Since we only need the values of [eagerFieldDependencies] for testing
        // and only the non-emptiness for determining the need for creation
        // order indices, [eagerFieldDependencies] is non-null if the field has
        // dependencies but only hold these when [retainDataForTesting] is
        // `true`.
        List<FieldEntity>? eagerFieldDependencies;
        int? creationIndex;

        if (isElided) {
          // If the field is elided it needs no initializer and is therefore
          // not eager.
          isEager = false;
        } else {
          // If the field has a constant initializer we know it can be
          // initialized eagerly.
          //
          // Ideally this should be the same as
          // `staticFieldData.complexity.isConstant` but currently the constant
          // evaluator handles cases that the analysis doesn't, so we use the
          // better result.
          isEager = value != null;
          if (!isEager) {
            // The field might be eager depending on the initializer complexity
            // and its dependencies.
            EvaluationComplexity complexity = staticFieldData.complexity;
            isEager = complexity.isEager;
            if (isEager && complexity.fields != null) {
              for (ir.Field node in complexity.fields!) {
                JField otherField =
                    closedWorld.elementMap.getField(node) as JField;
                FieldAnalysisData? otherData = processField(otherField);
                if (otherData == null) {
                  // Cyclic dependency on [otherField].
                  isEager = false;
                  break;
                }
                if (otherData.isLazy) {
                  // [otherField] needs lazy initialization.
                  isEager = false;
                  break;
                }
                if (!otherData.isEffectivelyFinal) {
                  // [otherField] might not hold its initial value when this field
                  // is accessed the first time, so we need to initialize this
                  // field lazily.
                  isEager = false;
                  break;
                }
                if (!otherData.isEffectivelyConstant) {
                  eagerFieldDependencies ??= [];
                  if (retainDataForTesting) {
                    eagerFieldDependencies.add(
                      map.toBackendMember(otherField) as FieldEntity,
                    );
                  }
                }
              }
            }
          }

          if (isEager && eagerFieldDependencies != null) {
            creationIndex = eagerCreationIndex++;
            if (!retainDataForTesting) {
              eagerFieldDependencies = null;
            }
          } else {
            eagerFieldDependencies = null;
          }
        }

        data = fieldData[jField] = FieldAnalysisData(
          initialValue: value,
          isEffectivelyFinal: isEffectivelyFinal,
          isElided: isElided,
          isEager: isEager,
          eagerCreationIndex: creationIndex,
          eagerFieldDependenciesForTesting: eagerFieldDependencies,
        );
      }

      currentFields.remove(kField);
      processedFields.add(kField);
      return data;
    }

    // Process independent fields in no particular order. The emitter sorts
    // these later.
    independentFields.forEach(processField);

    // Process dependent fields in declaration order to make ascribed creation
    // indices stable. The emitter uses the creation indices for sorting
    // dependent fields.
    dependentFields.sort((JField a, JField b) {
      int result = compareLibrariesUris(
        a.library.canonicalUri,
        b.library.canonicalUri,
      );
      if (result != 0) return result;
      ir.Location aLocation = closedWorld.elementMap.getMemberNode(a).location!;
      ir.Location bLocation = closedWorld.elementMap.getMemberNode(b).location!;
      result = compareSourceUris(aLocation.file, bLocation.file);
      if (result != 0) return result;
      result = aLocation.line.compareTo(bLocation.line);
      if (result != 0) return result;
      return aLocation.column.compareTo(bLocation.column);
    });

    dependentFields.forEach(processField);

    return JFieldAnalysis._(fieldData);
  }

  // TODO(sra): Add way to let injected fields be initialized to a constant in
  // allocator.

  FieldAnalysisData getFieldData(FieldEntity field) {
    assert(field is JField);
    return _fieldData[field] ?? const FieldAnalysisData();
  }
}

// TODO(johnniwinther): Merge this into [FieldData].
class FieldAnalysisData {
  static const String tag = 'field-analysis-data';

  final ConstantValue? initialValue;
  final bool isInitializedInAllocator;
  final bool isEffectivelyFinal;
  final bool isElided;

  /// The field has two values, an initial value and a subsequent value. The
  /// backing field for a `late final` instance field has this property.
  // TODO(sra): It might be possible to infer other fields have this property,
  // e.g. manual lazy fields initialized via `??=` to a not-null value.
  final bool isAssignedOnce;

  /// The field is a backing field for a late instance field.
  final bool isLateBackingField;

  /// If `true` the field is not effectively constant but the initializer can be
  /// generated eagerly without the need for lazy initialization wrapper.
  final bool isEager;

  /// Index ascribed to eager fields that depend on other fields. This is
  /// used to sort the field in emission to ensure that used fields have been
  /// initialized when read.
  final int? eagerCreationIndex;

  final List<FieldEntity>? eagerFieldDependenciesForTesting;

  const FieldAnalysisData({
    this.initialValue,
    this.isInitializedInAllocator = false,
    this.isEffectivelyFinal = false,
    this.isElided = false,
    this.isAssignedOnce = false,
    this.isLateBackingField = false,
    this.isEager = false,
    this.eagerCreationIndex,
    this.eagerFieldDependenciesForTesting,
  });

  factory FieldAnalysisData.fromDataSource(DataSourceReader source) {
    source.begin(tag);

    ConstantValue? initialValue = source.readConstantOrNull();
    bool isInitializedInAllocator = source.readBool();
    bool isEffectivelyFinal = source.readBool();
    bool isElided = source.readBool();
    bool isAssignedOnce = source.readBool();
    bool isLateBackingField = source.readBool();
    bool isEager = source.readBool();
    int? eagerCreationIndex = source.readIntOrNull();
    List<FieldEntity>? eagerFieldDependencies = source
        .readMembersOrNull<FieldEntity>();
    source.end(tag);
    return FieldAnalysisData(
      initialValue: initialValue,
      isInitializedInAllocator: isInitializedInAllocator,
      isEffectivelyFinal: isEffectivelyFinal,
      isElided: isElided,
      isAssignedOnce: isAssignedOnce,
      isLateBackingField: isLateBackingField,
      isEager: isEager,
      eagerCreationIndex: eagerCreationIndex,
      eagerFieldDependenciesForTesting: eagerFieldDependencies,
    );
  }

  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeConstantOrNull(initialValue);
    sink.writeBool(isInitializedInAllocator);
    sink.writeBool(isEffectivelyFinal);
    sink.writeBool(isElided);
    sink.writeBool(isAssignedOnce);
    sink.writeBool(isLateBackingField);
    sink.writeBool(isEager);
    sink.writeIntOrNull(eagerCreationIndex);
    sink.writeMembersOrNull(eagerFieldDependenciesForTesting);
    sink.end(tag);
  }

  /// If `true` the initializer for this field requires a lazy initialization
  /// wrapper.
  bool get isLazy => initialValue == null && !isEager;

  bool get isEffectivelyConstant =>
      isEffectivelyFinal && isElided && initialValue != null;

  ConstantValue? get constantValue => isEffectivelyFinal ? initialValue : null;

  @override
  String toString() =>
      'FieldAnalysisData('
      'initialValue=${initialValue?.toStructuredText(null)},'
      'isInitializedInAllocator=$isInitializedInAllocator,'
      'isEffectivelyFinal=$isEffectivelyFinal,'
      'isElided=$isElided,'
      'isAssignedOnce=$isAssignedOnce,'
      'isLateBackingField=$isLateBackingField,'
      'isEager=$isEager,'
      'eagerCreationIndex=$eagerCreationIndex,'
      'eagerFieldDependencies=$eagerFieldDependenciesForTesting)';
}
