// Copyright (c) 2016, 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 fasta.kernel_target;

import 'package:kernel/ast.dart';
import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
import 'package:kernel/type_algebra.dart' show Substitution;
import 'package:kernel/type_environment.dart';

import '../builder/library_builder.dart';
import '../messages.dart';

/// Data for clone default values for synthesized function nodes once the
/// original default values have been computed.
///
/// This is used for constructors in unnamed mixin application, which are
/// created from the constructors in the superclass, and for tear off lowerings
/// for redirecting factories, which are created from the effective target
/// constructor.
class SynthesizedFunctionNode {
  /// Type parameter map from type parameters in scope [_original] to types
  /// in scope of [_synthesized].
  // TODO(johnniwinther): Is this ever needed? Should occurrence of type
  //  variable types in default values be a compile time error?
  final Map<TypeParameter, DartType> _typeSubstitution;

  /// The original function node.
  final FunctionNode _original;

  /// The synthesized function node.
  final FunctionNode _synthesized;

  /// If `true`, the [_synthesized] is guaranteed to have the same parameters in
  /// the same order as [_original]. Otherwise [_original] is only guaranteed to
  /// be callable from [_synthesized], meaning that is has at most the same
  /// number of positional parameters and a, possibly reordered, subset of the
  /// named parameters.
  final bool identicalSignatures;

  final List<int?>? _positionalSuperParameters;

  final List<String>? _namedSuperParameters;

  bool isOutlineNode;

  final LibraryBuilder _libraryBuilder;

  CloneVisitorNotMembers? _cloner;

  SynthesizedFunctionNode(
      this._typeSubstitution, this._original, this._synthesized,
      {this.identicalSignatures: true,
      List<int?>? positionalSuperParameters: null,
      List<String>? namedSuperParameters: null,
      this.isOutlineNode: false,
      required LibraryBuilder libraryBuilder})
      : _positionalSuperParameters = positionalSuperParameters,
        _namedSuperParameters = namedSuperParameters,
        _libraryBuilder = libraryBuilder,
        // Check that [positionalSuperParameters] and [namedSuperParameters] are
        // provided or omitted together.
        assert((positionalSuperParameters == null) ==
            (namedSuperParameters == null)),
        assert(positionalSuperParameters == null ||
            () {
              // Check that [positionalSuperParameters] is sorted if it's
              // provided. The `null` values are allowed in-between the sorted
              // values.
              for (int i = -1, j = 0;
                  j < positionalSuperParameters.length;
                  j++) {
                int? currentValue = positionalSuperParameters[j];
                if (currentValue != null) {
                  if (i == -1 || positionalSuperParameters[i]! < currentValue) {
                    i = j;
                  } else {
                    return false;
                  }
                }
              }
              return true;
            }()),
        assert(namedSuperParameters == null ||
            () {
              // Check that [namedSuperParameters] are the subset of and in the
              // same order as the named parameters of [_synthesized].
              int superParameterIndex = 0;
              for (int namedParameterIndex = 0;
                  namedParameterIndex < _synthesized.namedParameters.length &&
                      superParameterIndex < namedSuperParameters.length;
                  namedParameterIndex++) {
                if (_synthesized.namedParameters[namedParameterIndex].name ==
                    namedSuperParameters[superParameterIndex]) {
                  ++superParameterIndex;
                }
              }
              return superParameterIndex == namedSuperParameters.length;
            }());

  void cloneDefaultValues(TypeEnvironment typeEnvironment) {
    // TODO(ahe): It is unclear if it is legal to use type variables in
    // default values, but Fasta is currently allowing it, and the VM
    // accepts it. If it isn't legal, the we can speed this up by using a
    // single cloner without substitution.

    // For mixin application constructors, the argument count is the same, but
    // for redirecting tear off lowerings, the argument count of the tear off
    // can be less than that of the redirection target or, in errors cases, be
    // unrelated.

    if (identicalSignatures) {
      assert(_positionalSuperParameters != null ||
          _synthesized.positionalParameters.length ==
              _original.positionalParameters.length);
      List<int?>? positionalSuperParameters = _positionalSuperParameters;
      for (int i = 0; i < _original.positionalParameters.length; i++) {
        if (positionalSuperParameters == null) {
          _cloneInitializer(_original.positionalParameters[i],
              _synthesized.positionalParameters[i]);
        } else if (i < positionalSuperParameters.length) {
          int? superParameterIndex = positionalSuperParameters[i];
          if (superParameterIndex != null) {
            VariableDeclaration originalParameter =
                _original.positionalParameters[i];
            VariableDeclaration synthesizedParameter =
                _synthesized.positionalParameters[superParameterIndex];
            _cloneDefaultValueForSuperParameters(
                originalParameter, synthesizedParameter, typeEnvironment);
          }
        }
      }

      assert(_namedSuperParameters != null ||
          _synthesized.namedParameters.length ==
              _original.namedParameters.length);
      List<String>? namedSuperParameters = _namedSuperParameters;
      int superParameterNameIndex = 0;
      Map<String, int> originalNamedParameterIndices = {};
      for (int i = 0; i < _original.namedParameters.length; i++) {
        originalNamedParameterIndices[_original.namedParameters[i].name!] = i;
      }
      for (int i = 0; i < _synthesized.namedParameters.length; i++) {
        if (namedSuperParameters == null) {
          _cloneInitializer(
              _original.namedParameters[i], _synthesized.namedParameters[i]);
        } else if (superParameterNameIndex < namedSuperParameters.length &&
            namedSuperParameters[superParameterNameIndex] ==
                _synthesized.namedParameters[i].name) {
          String superParameterName =
              namedSuperParameters[superParameterNameIndex];
          int? originalNamedParameterIndex =
              originalNamedParameterIndices[superParameterName];
          if (originalNamedParameterIndex != null) {
            VariableDeclaration originalParameter =
                _original.namedParameters[originalNamedParameterIndex];
            VariableDeclaration synthesizedParameter =
                _synthesized.namedParameters[i];
            _cloneDefaultValueForSuperParameters(
                originalParameter, synthesizedParameter, typeEnvironment);
          } else {
            // TODO(cstefantsova): Handle the erroneous case of missing names.
          }
          superParameterNameIndex++;
        }
      }
    } else {
      for (int i = 0; i < _synthesized.positionalParameters.length; i++) {
        VariableDeclaration synthesizedParameter =
            _synthesized.positionalParameters[i];
        if (i < _original.positionalParameters.length) {
          _cloneInitializer(
              _original.positionalParameters[i], synthesizedParameter);
        } else {
          // Error case: use `null` as initializer.
          synthesizedParameter.initializer = new NullLiteral()
            ..parent = synthesizedParameter;
        }
      }
      if (_synthesized.namedParameters.isNotEmpty) {
        Map<String, VariableDeclaration> originalParameters = {};
        for (int i = 0; i < _original.namedParameters.length; i++) {
          originalParameters[_original.namedParameters[i].name!] =
              _original.namedParameters[i];
        }
        for (int i = 0; i < _synthesized.namedParameters.length; i++) {
          VariableDeclaration synthesizedParameter =
              _synthesized.namedParameters[i];
          VariableDeclaration? originalParameter =
              originalParameters[synthesizedParameter.name!];
          if (originalParameter != null) {
            _cloneInitializer(originalParameter, synthesizedParameter);
          } else {
            // Error case: use `null` as initializer.
            synthesizedParameter.initializer = new NullLiteral()
              ..parent = synthesizedParameter;
          }
        }
      }
    }
  }

  void _cloneInitializer(VariableDeclaration originalParameter,
      VariableDeclaration clonedParameter) {
    if (originalParameter.initializer != null) {
      CloneVisitorNotMembers cloner = _cloner ??=
          new CloneVisitorNotMembers(typeSubstitution: _typeSubstitution);
      clonedParameter.initializer = cloner.clone(originalParameter.initializer!)
        ..parent = clonedParameter;
    }
  }

  void _cloneDefaultValueForSuperParameters(
      VariableDeclaration originalParameter,
      VariableDeclaration synthesizedParameter,
      TypeEnvironment typeEnvironment) {
    Member member = _synthesized.parent as Member;
    Expression? originalParameterInitializer = originalParameter.initializer;
    DartType? originalParameterInitializerType = originalParameterInitializer
        ?.getStaticType(new StaticTypeContext(member, typeEnvironment));
    DartType synthesizedParameterType = synthesizedParameter.type;
    if (originalParameterInitializerType != null &&
        typeEnvironment.isSubtypeOf(originalParameterInitializerType,
            synthesizedParameterType, SubtypeCheckMode.withNullabilities)) {
      _cloneInitializer(originalParameter, synthesizedParameter);
    } else {
      if (synthesizedParameterType.isPotentiallyNonNullable) {
        _libraryBuilder.addProblem(
            templateOptionalSuperParameterWithoutInitializer.withArguments(
                synthesizedParameter.type,
                synthesizedParameter.name!,
                _libraryBuilder.isNonNullableByDefault),
            synthesizedParameter.fileOffset,
            synthesizedParameter.name?.length ?? 1,
            _libraryBuilder.fileUri);
      }
    }
  }

  @override
  String toString() {
    return "SynthesizedFunctionNode(original=${_original.parent}, "
        "synthesized=${_synthesized.parent})";
  }
}

class TypeDependency {
  final Member synthesized;
  final Member original;
  final Substitution substitution;
  final bool copyReturnType;

  TypeDependency(this.synthesized, this.original, this.substitution,
      {required this.copyReturnType});

  void copyInferred() {
    for (int i = 0; i < original.function!.positionalParameters.length; i++) {
      VariableDeclaration synthesizedParameter =
          synthesized.function!.positionalParameters[i];
      VariableDeclaration constructorParameter =
          original.function!.positionalParameters[i];
      synthesizedParameter.type =
          substitution.substituteType(constructorParameter.type);
    }
    for (int i = 0; i < original.function!.namedParameters.length; i++) {
      VariableDeclaration synthesizedParameter =
          synthesized.function!.namedParameters[i];
      VariableDeclaration originalParameter =
          original.function!.namedParameters[i];
      synthesizedParameter.type =
          substitution.substituteType(originalParameter.type);
    }
    if (copyReturnType) {
      synthesized.function!.returnType =
          substitution.substituteType(original.function!.returnType);
    }
  }
}
