// Copyright (c) 2019, 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";

import 'package:kernel/transformations/flags.dart' show TransformerFlag;
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';

import "../source/source_class_builder.dart";

import "../problems.dart" show unhandled;

import 'class_hierarchy_builder.dart';
import 'combined_member_signature.dart';

class ForwardingNode {
  final CombinedClassMemberSignature _combinedMemberSignature;

  final ProcedureKind kind;

  final ClassMember? _superClassMember;

  final ClassMember? _mixedInMember;

  ForwardingNode(this._combinedMemberSignature, this.kind,
      this._superClassMember, this._mixedInMember);

  /// Finishes handling of this node by propagating covariance and creating
  /// forwarding stubs if necessary.
  ///
  /// If a stub is created, this is returned. Otherwise `null` is returned.
  Procedure? finalize() => _computeCovarianceFixes();

  /// Tag the parameters of [interfaceMember] that need type checks
  ///
  /// Parameters can need type checks for calls coming from statically typed
  /// call sites, due to covariant generics and overrides with explicit
  /// `covariant` parameters.
  ///
  /// Tag parameters of [interfaceMember] that need such checks when the member
  /// occurs in [enclosingClass]'s interface.  If parameters need checks but
  /// they would not be checked in an inherited implementation, a forwarding
  /// stub is introduced as a place to put the checks.
  ///
  /// If a stub is created, this is returned. Otherwise `null` is returned.
  Procedure? _computeCovarianceFixes() {
    SourceClassBuilder classBuilder = _combinedMemberSignature.classBuilder;
    ClassMember canonicalMember = _combinedMemberSignature.canonicalMember!;
    Member interfaceMember =
        canonicalMember.getMember(_combinedMemberSignature.hierarchy);

    bool needMixinStub =
        classBuilder.isMixinApplication && _mixedInMember != null;

    if (_combinedMemberSignature.members.length == 1 && !needMixinStub) {
      // Covariance can only come from [interfaceMember] so we never need a
      // forwarding stub.
      if (_combinedMemberSignature.neededLegacyErasure) {
        return _combinedMemberSignature.createMemberFromSignature(
            // TODO(johnniwinther): Change member signatures to use location
            // of origin.
            copyLocation: false);
      } else {
        // Nothing to do.
        return null;
      }
    }

    // TODO(johnniwinther): Remove this. This relies upon the order of the
    // declarations matching the order in which members are returned from the
    // [ClassHierarchy].
    bool cannotReuseExistingMember =
        !(_combinedMemberSignature.isCanonicalMemberFirst ||
            _combinedMemberSignature.isCanonicalMemberDeclared);
    bool needsTypeOrCovarianceUpdate =
        _combinedMemberSignature.neededNnbdTopMerge ||
            _combinedMemberSignature.neededLegacyErasure ||
            _combinedMemberSignature.needsCovarianceMerging;
    bool stubNeeded = cannotReuseExistingMember ||
        (canonicalMember.classBuilder != classBuilder &&
            needsTypeOrCovarianceUpdate) ||
        needMixinStub;
    bool needsSuperImpl = _superClassMember != null &&
        _superClassMember!.getCovariance(_combinedMemberSignature.hierarchy) !=
            _combinedMemberSignature.combinedMemberSignatureCovariance;
    if (stubNeeded) {
      Procedure stub = _combinedMemberSignature.createMemberFromSignature(
          copyLocation: false)!;
      bool needsForwardingStub =
          _combinedMemberSignature.needsCovarianceMerging || needsSuperImpl;
      if (needsForwardingStub || needMixinStub) {
        ProcedureStubKind stubKind;
        Member finalTarget;
        if (needsForwardingStub) {
          stubKind = ProcedureStubKind.AbstractForwardingStub;
          if (interfaceMember is Procedure) {
            switch (interfaceMember.stubKind) {
              case ProcedureStubKind.Regular:
              case ProcedureStubKind.NoSuchMethodForwarder:
                finalTarget = interfaceMember;
                break;
              case ProcedureStubKind.AbstractForwardingStub:
              case ProcedureStubKind.ConcreteForwardingStub:
              case ProcedureStubKind.MemberSignature:
              case ProcedureStubKind.AbstractMixinStub:
              case ProcedureStubKind.ConcreteMixinStub:
                finalTarget = interfaceMember.stubTarget!;
                break;
            }
          } else {
            finalTarget = interfaceMember;
          }
        } else {
          stubKind = ProcedureStubKind.AbstractMixinStub;
          finalTarget =
              _mixedInMember!.getMember(_combinedMemberSignature.hierarchy);
        }

        stub.stubKind = stubKind;
        stub.stubTarget = finalTarget;
        if (needsSuperImpl ||
            (needMixinStub && _superClassMember == _mixedInMember)) {
          _createForwardingImplIfNeeded(
              stub.function, stub.name, classBuilder.cls,
              isForwardingStub: needsForwardingStub);
        }
      }

      return stub;
    } else {
      if (_combinedMemberSignature.needsCovarianceMerging) {
        _combinedMemberSignature.combinedMemberSignatureCovariance!
            .applyCovariance(interfaceMember);
      }
      if (needsSuperImpl) {
        _createForwardingImplIfNeeded(
            interfaceMember.function!, interfaceMember.name, classBuilder.cls,
            isForwardingStub: true);
      }
      return null;
    }
  }

  void _createForwardingImplIfNeeded(
      FunctionNode function, Name name, Class enclosingClass,
      {required bool isForwardingStub}) {
    // ignore: unnecessary_null_comparison
    assert(isForwardingStub != null);
    if (function.body != null) {
      // There is already an implementation; nothing further needs to be done.
      return;
    }
    // If there is no concrete implementation in the superclass, then the method
    // is fully abstract and we don't need to do anything.
    if (_superClassMember == null) {
      return;
    }
    Procedure procedure = function.parent as Procedure;
    Member superTarget =
        _superClassMember!.getMember(_combinedMemberSignature.hierarchy);
    if (superTarget is Procedure && superTarget.isForwardingStub) {
      Procedure superProcedure = superTarget;
      superTarget = superProcedure.concreteForwardingStubTarget!;
    } else {
      superTarget = superTarget.memberSignatureOrigin ?? superTarget;
    }
    procedure.isAbstract = false;
    FunctionType signatureType = procedure.function
        .computeFunctionType(procedure.enclosingLibrary.nonNullable);
    bool isForwardingSemiStub = isForwardingStub && !procedure.isSynthetic;
    bool needsSignatureType = false;
    Expression superCall;
    // ignore: unnecessary_null_comparison
    assert(superTarget != null,
        "No super target found for '${name}' in ${enclosingClass}.");
    assert(
        !superTarget.isAbstract,
        "Abstract super target $superTarget found for '${name}' in "
        "${enclosingClass}.");
    switch (kind) {
      case ProcedureKind.Method:
      case ProcedureKind.Operator:
        FunctionType type = _combinedMemberSignature
            .getMemberTypeForTarget(superTarget) as FunctionType;
        if (type.typeParameters.isNotEmpty) {
          type = Substitution.fromPairs(
                  type.typeParameters,
                  function.typeParameters
                      .map((TypeParameter parameter) => new TypeParameterType
                              .withDefaultNullabilityForLibrary(
                          parameter, procedure.enclosingLibrary))
                      .toList())
              .substituteType(type.withoutTypeParameters) as FunctionType;
        }
        List<Expression> positionalArguments = new List.generate(
            function.positionalParameters.length, (int index) {
          VariableDeclaration parameter = function.positionalParameters[index];
          int fileOffset = parameter.fileOffset;
          Expression expression = new VariableGet(parameter)
            ..fileOffset = fileOffset;
          DartType superParameterType = type.positionalParameters[index];
          if (isForwardingSemiStub) {
            if (parameter.type != superParameterType) {
              parameter.type = superParameterType;
              needsSignatureType = true;
            }
          } else {
            if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
                parameter.type,
                superParameterType,
                _combinedMemberSignature
                        .classBuilder.library.isNonNullableByDefault
                    ? SubtypeCheckMode.withNullabilities
                    : SubtypeCheckMode.ignoringNullabilities)) {
              expression = new AsExpression(expression, superParameterType)
                ..fileOffset = fileOffset;
            }
          }
          return expression;
        }, growable: true);
        List<NamedExpression> namedArguments =
            new List.generate(function.namedParameters.length, (int index) {
          VariableDeclaration parameter = function.namedParameters[index];
          int fileOffset = parameter.fileOffset;
          Expression expression = new VariableGet(parameter)
            ..fileOffset = fileOffset;
          DartType superParameterType = type.namedParameters
              .singleWhere(
                  (NamedType namedType) => namedType.name == parameter.name)
              .type;
          if (isForwardingSemiStub) {
            if (parameter.type != superParameterType) {
              parameter.type = superParameterType;
              needsSignatureType = true;
            }
          } else {
            if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
                parameter.type,
                superParameterType,
                _combinedMemberSignature
                        .classBuilder.library.isNonNullableByDefault
                    ? SubtypeCheckMode.withNullabilities
                    : SubtypeCheckMode.ignoringNullabilities)) {
              expression = new AsExpression(expression, superParameterType)
                ..fileOffset = fileOffset;
            }
          }
          return new NamedExpression(parameter.name!, expression);
        }, growable: true);
        List<DartType> typeArguments = function.typeParameters
            .map<DartType>((typeParameter) =>
                new TypeParameterType.withDefaultNullabilityForLibrary(
                    typeParameter, enclosingClass.enclosingLibrary))
            .toList();
        Arguments arguments = new Arguments(positionalArguments,
            types: typeArguments, named: namedArguments);
        superCall = new SuperMethodInvocation(
            name, arguments, superTarget as Procedure);
        break;
      case ProcedureKind.Getter:
        superCall = new SuperPropertyGet(name, superTarget);
        break;
      case ProcedureKind.Setter:
        DartType superParameterType =
            _combinedMemberSignature.getMemberTypeForTarget(superTarget);
        VariableDeclaration parameter = function.positionalParameters[0];
        int fileOffset = parameter.fileOffset;
        Expression expression = new VariableGet(parameter)
          ..fileOffset = fileOffset;
        if (isForwardingSemiStub) {
          if (parameter.type != superParameterType) {
            parameter.type = superParameterType;
            needsSignatureType = true;
          }
        } else {
          if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
              parameter.type,
              superParameterType,
              _combinedMemberSignature
                      .classBuilder.library.isNonNullableByDefault
                  ? SubtypeCheckMode.withNullabilities
                  : SubtypeCheckMode.ignoringNullabilities)) {
            expression = new AsExpression(expression, superParameterType)
              ..fileOffset = fileOffset;
          }
        }
        superCall = new SuperPropertySet(name, expression, superTarget);
        break;
      default:
        unhandled('$kind', '_createForwardingImplIfNeeded', -1, null);
    }
    function.body = new ReturnStatement(superCall)
      ..fileOffset = procedure.fileOffset
      ..parent = function;
    procedure.transformerFlags |= TransformerFlag.superCalls;
    procedure.stubKind = isForwardingStub
        ? ProcedureStubKind.ConcreteForwardingStub
        : ProcedureStubKind.ConcreteMixinStub;
    procedure.stubTarget = superTarget;
    if (needsSignatureType) {
      procedure.signatureType = signatureType;
    }
  }
}
