// 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:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/generated/type_system.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';

class TopMergeHelper {
  final TypeSystemImpl typeSystem;

  TopMergeHelper(this.typeSystem);

  /**
   * Merges two types into a single type.
   * Compute the canonical representation of [T].
   *
   * https://github.com/dart-lang/language/
   * See `accepted/future-releases/nnbd/feature-specification.md`
   * See `#classes-defined-in-opted-in-libraries`
   */
  DartType topMerge(DartType T, DartType S) {
    var T_nullability = T.nullabilitySuffix;
    var S_nullability = S.nullabilitySuffix;

    // NNBD_TOP_MERGE(Object?, Object?) = Object?
    var T_isObjectQuestion =
        T_nullability == NullabilitySuffix.question && T.isDartCoreObject;
    var S_isObjectQuestion =
        S_nullability == NullabilitySuffix.question && S.isDartCoreObject;
    if (T_isObjectQuestion && S_isObjectQuestion) {
      return T;
    }

    // NNBD_TOP_MERGE(dynamic, dynamic) = dynamic
    var T_isDynamic = identical(T, DynamicTypeImpl.instance);
    var S_isDynamic = identical(S, DynamicTypeImpl.instance);
    if (T_isDynamic && S_isDynamic) {
      return DynamicTypeImpl.instance;
    }

    if (identical(T, NeverTypeImpl.instance) &&
        identical(S, NeverTypeImpl.instance)) {
      return NeverTypeImpl.instance;
    }

    // NNBD_TOP_MERGE(void, void) = void
    var T_isVoid = identical(T, VoidTypeImpl.instance);
    var S_isVoid = identical(S, VoidTypeImpl.instance);
    if (T_isVoid && S_isVoid) {
      return VoidTypeImpl.instance;
    }

    // NNBD_TOP_MERGE(Object?, void) = void
    // NNBD_TOP_MERGE(void, Object?) = void
    if (T_isObjectQuestion && S_isVoid || T_isVoid && S_isObjectQuestion) {
      return typeSystem.objectQuestion;
    }

    // NNBD_TOP_MERGE(Object*, void) = void
    // NNBD_TOP_MERGE(void, Object*) = void
    var T_isObjectStar =
        T_nullability == NullabilitySuffix.star && T.isDartCoreObject;
    var S_isObjectStar =
        S_nullability == NullabilitySuffix.star && S.isDartCoreObject;
    if (T_isObjectStar && S_isVoid || T_isVoid && S_isObjectStar) {
      return typeSystem.objectQuestion;
    }

    // NNBD_TOP_MERGE(dynamic, void) = void
    // NNBD_TOP_MERGE(void, dynamic) = void
    if (T_isDynamic && S_isVoid || T_isVoid && S_isDynamic) {
      return typeSystem.objectQuestion;
    }

    // NNBD_TOP_MERGE(Object?, dynamic) = Object?
    // NNBD_TOP_MERGE(dynamic, Object?) = Object?
    if (T_isObjectQuestion && S_isDynamic) {
      return T;
    }
    if (T_isDynamic && S_isObjectQuestion) {
      return S;
    }

    // NNBD_TOP_MERGE(Object*, dynamic) = Object?
    // NNBD_TOP_MERGE(dynamic, Object*) = Object?
    if (T_isObjectStar && S_isDynamic || T_isDynamic && S_isObjectStar) {
      return typeSystem.objectQuestion;
    }

    // NNBD_TOP_MERGE(Never*, Null) = Null
    // NNBD_TOP_MERGE(Null, Never*) = Null
    if (identical(T, NeverTypeImpl.instanceLegacy) &&
        S_nullability == NullabilitySuffix.none &&
        S.isDartCoreNull) {
      return S;
    }
    if (T_nullability == NullabilitySuffix.none &&
        T.isDartCoreNull &&
        identical(S, NeverTypeImpl.instanceLegacy)) {
      return T;
    }

    // Merge nullabilities.
    var T_isNone = T_nullability == NullabilitySuffix.none;
    var S_isNone = S_nullability == NullabilitySuffix.none;
    if (!T_isNone || !S_isNone) {
      var T_isQuestion = T_nullability == NullabilitySuffix.question;
      var T_isStar = T_nullability == NullabilitySuffix.star;

      var S_isQuestion = S_nullability == NullabilitySuffix.question;
      var S_isStar = S_nullability == NullabilitySuffix.star;

      NullabilitySuffix resultNullability;
      if (T_isQuestion && S_isQuestion ||
          T_isQuestion && S_isStar ||
          T_isStar && S_isQuestion) {
        // NNBD_TOP_MERGE(T?, S?) = NNBD_TOP_MERGE(T, S)?
        // NNBD_TOP_MERGE(T?, S*) = NNBD_TOP_MERGE(T, S)?
        // NNBD_TOP_MERGE(T*, S?) = NNBD_TOP_MERGE(T, S)?
        resultNullability = NullabilitySuffix.question;
      } else if (T_isStar && S_isStar) {
        // NNBD_TOP_MERGE(T*, S*) = NNBD_TOP_MERGE(T, S)*
        resultNullability = NullabilitySuffix.star;
      } else if (T_isStar && S_isNone || T_isNone && S_isStar) {
        // NNBD_TOP_MERGE(T*, S) = NNBD_TOP_MERGE(T, S)
        // NNBD_TOP_MERGE(T, S*) = NNBD_TOP_MERGE(T, S)
        resultNullability = NullabilitySuffix.none;
      } else {
        throw StateError('$T_nullability vs $S_nullability');
      }

      var T_none = (T as TypeImpl).withNullability(NullabilitySuffix.none);
      var S_none = (S as TypeImpl).withNullability(NullabilitySuffix.none);
      var R_none = topMerge(T_none, S_none) as TypeImpl;
      return R_none?.withNullability(resultNullability);
    }

    assert(T_nullability == NullabilitySuffix.none);
    assert(S_nullability == NullabilitySuffix.none);

    // And for all other types, recursively apply the transformation over
    // the structure of the type.
    //
    // For example: NNBD_TOP_MERGE(C<T>, C<S>) = C<NNBD_TOP_MERGE(T, S)>
    //
    // The NNBD_TOP_MERGE of two types is not defined for types which are not
    // otherwise structurally equal.

    if (T is InterfaceType && S is InterfaceType) {
      return _interfaceTypes(T, S);
    }

    if (T is FunctionType && S is FunctionType) {
      return _functionTypes(T, S);
    }

    if (T is TypeParameterType && S is TypeParameterType) {
      if (T.element == S.element) {
        return T;
      } else {
        throw _TopMergeStateError(T, S, 'Not the same type parameters');
      }
    }

    throw _TopMergeStateError(T, S, 'Unexpected pair');
  }

  FunctionTypeImpl _functionTypes(FunctionType T, FunctionType S) {
    var T_typeParameters = T.typeFormals;
    var S_typeParameters = S.typeFormals;
    if (T_typeParameters.length != S_typeParameters.length) {
      throw _TopMergeStateError(T, S, 'Different number of type parameters');
    }

    List<TypeParameterElement> R_typeParameters;
    Substitution T_Substitution;
    Substitution S_Substitution;

    DartType mergeTypes(DartType T, DartType S) {
      if (T_Substitution != null) {
        T = T_Substitution.substituteType(T);
        S = S_Substitution.substituteType(S);
      }
      return topMerge(T, S);
    }

    if (T_typeParameters.isNotEmpty) {
      var mergedTypeParameters = _typeParameters(
        T_typeParameters,
        S_typeParameters,
      );
      if (mergedTypeParameters == null) {
        throw _TopMergeStateError(T, S, 'Unable to merge type parameters');
      }
      R_typeParameters = mergedTypeParameters.typeParameters;
      T_Substitution = mergedTypeParameters.aSubstitution;
      S_Substitution = mergedTypeParameters.bSubstitution;
    } else {
      R_typeParameters = const <TypeParameterElement>[];
    }

    var R_returnType = mergeTypes(T.returnType, S.returnType);

    var T_parameters = T.parameters;
    var S_parameters = S.parameters;
    if (T_parameters.length != S_parameters.length) {
      throw _TopMergeStateError(T, S, 'Different number of formal parameters');
    }

    var R_parameters = List<ParameterElement>(T_parameters.length);
    for (var i = 0; i < T_parameters.length; i++) {
      var T_parameter = T_parameters[i];
      var S_parameter = S_parameters[i];

      var R_kind = _parameterKind(T_parameter, S_parameter);
      if (R_kind == null) {
        throw _TopMergeStateError(T, S, 'Different formal parameter kinds');
      }

      if (T_parameter.isNamed && T_parameter.name != S_parameter.name) {
        throw _TopMergeStateError(T, S, 'Different named parameter names');
      }

      DartType R_type;

      // Given two corresponding parameters of type `T1` and `T2`, where at least
      // one of the parameters is covariant:
      var T_isCovariant = T_parameter.isCovariant;
      var S_isCovariant = S_parameter.isCovariant;
      var R_isCovariant = T_isCovariant || S_isCovariant;
      if (R_isCovariant) {
        var T1 = T_parameter.type;
        var T2 = S_parameter.type;
        var T1_isSubtype = typeSystem.isSubtypeOf2(T1, T2);
        var T2_isSubtype = typeSystem.isSubtypeOf2(T2, T1);
        if (T1_isSubtype && T2_isSubtype) {
          // if `T1 <: T2` and `T2 <: T1`, then the result is
          // `NNBD_TOP_MERGE(T1, T2)`, and it is covariant.
          R_type = mergeTypes(T_parameter.type, S_parameter.type);
        } else if (T1_isSubtype) {
          // otherwise, if `T1 <: T2`, then the result is
          // `T2` and it is covariant.
          R_type = T2;
        } else {
          // otherwise, the result is `T1` and it is covariant.
          R_type = T1;
        }
      } else {
        R_type = mergeTypes(T_parameter.type, S_parameter.type);
      }

      R_parameters[i] = ParameterElementImpl.synthetic(
        T_parameter.name,
        R_type,
        R_kind,
      )..isExplicitlyCovariant = R_isCovariant;
    }

    return FunctionTypeImpl(
      typeFormals: R_typeParameters,
      parameters: R_parameters,
      returnType: R_returnType,
      nullabilitySuffix: NullabilitySuffix.none,
    );
  }

  InterfaceType _interfaceTypes(InterfaceType T, InterfaceType S) {
    if (T.element != S.element) {
      throw _TopMergeStateError(T, S, 'Different class elements');
    }

    var T_arguments = T.typeArguments;
    var S_arguments = S.typeArguments;
    if (T_arguments.isEmpty) {
      return T;
    } else {
      var arguments = List<DartType>(T_arguments.length);
      for (var i = 0; i < T_arguments.length; i++) {
        arguments[i] = topMerge(T_arguments[i], S_arguments[i]);
      }
      return T.element.instantiate(
        typeArguments: arguments,
        nullabilitySuffix: NullabilitySuffix.none,
      );
    }
  }

  ParameterKind _parameterKind(
    ParameterElement T_parameter,
    ParameterElement S_parameter,
  ) {
    // ignore: deprecated_member_use_from_same_package
    var T_kind = T_parameter.parameterKind;

    // ignore: deprecated_member_use_from_same_package
    var S_kind = S_parameter.parameterKind;

    if (T_kind == S_kind) {
      return T_kind;
    }

    // Legacy named vs. Required named.
    if (T_kind == ParameterKind.NAMED_REQUIRED &&
            S_kind == ParameterKind.NAMED ||
        T_kind == ParameterKind.NAMED &&
            S_kind == ParameterKind.NAMED_REQUIRED) {
      return ParameterKind.NAMED_REQUIRED;
    }

    return null;
  }

  _MergeTypeParametersResult _typeParameters(
    List<TypeParameterElement> aParameters,
    List<TypeParameterElement> bParameters,
  ) {
    if (aParameters.length != bParameters.length) {
      return null;
    }

    var newParameters = <TypeParameterElementImpl>[];
    var newTypes = <TypeParameterType>[];
    for (var i = 0; i < aParameters.length; i++) {
      var name = aParameters[i].name;
      var newParameter = TypeParameterElementImpl.synthetic(name);
      newParameters.add(newParameter);

      var newType = newParameter.instantiate(
        nullabilitySuffix: NullabilitySuffix.none,
      );
      newTypes.add(newType);
    }

    var aSubstitution = Substitution.fromPairs(aParameters, newTypes);
    var bSubstitution = Substitution.fromPairs(bParameters, newTypes);
    for (var i = 0; i < aParameters.length; i++) {
      var a = aParameters[i];
      var b = bParameters[i];

      var aBound = a.bound;
      var bBound = b.bound;
      if (aBound == null && bBound == null) {
        // OK, no bound.
      } else if (aBound != null && bBound != null) {
        aBound = aSubstitution.substituteType(aBound);
        bBound = bSubstitution.substituteType(bBound);
        var newBound = topMerge(aBound, bBound);
        newParameters[i].bound = newBound;
      } else {
        return null;
      }
    }

    return _MergeTypeParametersResult(
      newParameters,
      aSubstitution,
      bSubstitution,
    );
  }
}

class _MergeTypeParametersResult {
  final List<TypeParameterElement> typeParameters;
  final Substitution aSubstitution;
  final Substitution bSubstitution;

  _MergeTypeParametersResult(
    this.typeParameters,
    this.aSubstitution,
    this.bSubstitution,
  );
}

/// This error should never happen, because we should never attempt
/// `NNBD_TOP_MERGE` for types that are not subtypes of each other, and
/// already NORM(ed).
class _TopMergeStateError {
  final DartType T;
  final DartType S;
  final String message;

  _TopMergeStateError(this.T, this.S, this.message);
}
