// Copyright (c) 2020, 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/dart/element/type_visitor.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/dart/element/type_system.dart';

class RuntimeTypeEqualityHelper {
  final TypeSystemImpl _typeSystem;

  RuntimeTypeEqualityHelper(TypeSystemImpl typeSystem)
      : _typeSystem = typeSystem;

  /// Return `true` if runtime types [T1] and [T2] are equal.
  ///
  /// nnbd/feature-specification.md#runtime-type-equality-operator
  bool equal(DartType T1, DartType T2) {
    var N1 = _typeSystem.normalize(T1);
    var N2 = _typeSystem.normalize(T2);
    return N1.acceptWithArgument(const RuntimeTypeEqualityVisitor(), N2);
  }
}

class RuntimeTypeEqualityVisitor
    extends TypeVisitorWithArgument<bool, DartType> {
  const RuntimeTypeEqualityVisitor();

  @override
  bool visitDynamicType(DynamicType T1, DartType T2) {
    return identical(T1, T2);
  }

  @override
  bool visitFunctionType(FunctionType T1, DartType T2) {
    if (T2 is FunctionType) {
      var typeParameters = _typeParameters(T1.typeFormals, T2.typeFormals);
      if (typeParameters == null) {
        return false;
      }

      bool equal(DartType T1, DartType T2) {
        T1 = typeParameters.T1_substitution.substituteType(T1);
        T2 = typeParameters.T2_substitution.substituteType(T2);
        return T1.acceptWithArgument(this, T2);
      }

      if (!equal(T1.returnType, T2.returnType)) {
        return false;
      }

      var T1_parameters = T1.parameters;
      var T2_parameters = T2.parameters;
      if (T1_parameters.length != T2_parameters.length) {
        return false;
      }

      for (var i = 0; i < T1_parameters.length; i++) {
        var T1_parameter = T1_parameters[i];
        var T2_parameter = T2_parameters[i];

        // ignore: deprecated_member_use_from_same_package
        if (T1_parameter.parameterKind != T2_parameter.parameterKind) {
          return false;
        }

        if (T1_parameter.isNamed) {
          if (T1_parameter.name != T2_parameter.name) {
            return false;
          }
        }

        if (!equal(T1_parameter.type, T2_parameter.type)) {
          return false;
        }
      }

      return true;
    }
    return false;
  }

  @override
  bool visitInterfaceType(InterfaceType T1, DartType T2) {
    if (T2 is InterfaceType &&
        T1.element == T2.element &&
        _compatibleNullability(T1, T2)) {
      var T1_typeArguments = T1.typeArguments;
      var T2_typeArguments = T2.typeArguments;
      if (T1_typeArguments.length == T2_typeArguments.length) {
        for (var i = 0; i < T1_typeArguments.length; i++) {
          var T1_typeArgument = T1_typeArguments[i];
          var T2_typeArgument = T2_typeArguments[i];
          if (!T1_typeArgument.acceptWithArgument(this, T2_typeArgument)) {
            return false;
          }
        }
        return true;
      }
    }
    return false;
  }

  @override
  bool visitNeverType(NeverType T1, DartType T2) {
    // Note, that all types are normalized before this visitor.
    // So, `Never?` never happens, it is already `Null`.
    assert(T1.nullabilitySuffix != NullabilitySuffix.question);
    return T2 is NeverTypeImpl && _compatibleNullability(T1, T2);
  }

  @override
  bool visitTypeParameterType(TypeParameterType T1, DartType T2) {
    return T2 is TypeParameterType &&
        _compatibleNullability(T1, T2) &&
        T1.element == T2.element;
  }

  @override
  bool visitVoidType(VoidType T1, DartType T2) {
    return identical(T1, T2);
  }

  bool _compatibleNullability(DartType T1, DartType T2) {
    var T1_nullability = T1.nullabilitySuffix;
    var T2_nullability = T2.nullabilitySuffix;
    return T1_nullability == T2_nullability ||
        T1_nullability == NullabilitySuffix.star &&
            T2_nullability == NullabilitySuffix.none ||
        T2_nullability == NullabilitySuffix.star &&
            T1_nullability == NullabilitySuffix.none;
  }

  /// Determines if the two lists of type parameters are equal.  If they are,
  /// returns a [_TypeParametersResult] indicating the substitutions necessary
  /// to demonstrate their equality.  If they aren't, returns `null`.
  _TypeParametersResult? _typeParameters(
    List<TypeParameterElement> T1_parameters,
    List<TypeParameterElement> T2_parameters,
  ) {
    if (T1_parameters.length != T2_parameters.length) {
      return null;
    }

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

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

    var T1_substitution = Substitution.fromPairs(T1_parameters, newTypes);
    var T2_substitution = Substitution.fromPairs(T2_parameters, newTypes);
    for (var i = 0; i < T1_parameters.length; i++) {
      var T1_parameter = T1_parameters[i];
      var T2_parameter = T2_parameters[i];

      var T1_bound = T1_parameter.bound;
      var T2_bound = T2_parameter.bound;
      if (T1_bound == null && T2_bound == null) {
        // OK, no bound.
      } else if (T1_bound != null && T2_bound != null) {
        T1_bound = T1_substitution.substituteType(T1_bound);
        T2_bound = T2_substitution.substituteType(T2_bound);
        if (!T1_bound.acceptWithArgument(this, T2_bound)) {
          return null;
        }
      } else {
        return null;
      }
    }

    return _TypeParametersResult(T1_substitution, T2_substitution);
  }
}

class _TypeParametersResult {
  final Substitution T1_substitution;
  final Substitution T2_substitution;

  _TypeParametersResult(this.T1_substitution, this.T2_substitution);
}
