// 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/dart/element/type_provider.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:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/nullability_node_target.dart';

/// Representation of a type in the code to be migrated.  In addition to
/// tracking the (unmigrated) [DartType], we track the [ConstraintVariable]s
/// indicating whether the type, and the types that compose it, are nullable.
class DecoratedType implements DecoratedTypeInfo {
  @override
  final DartType? type;

  @override
  final NullabilityNode? node;

  @override
  final DecoratedType? returnType;

  /// If `this` is a function type, the [DecoratedType] of each of its
  /// positional parameters (including both required and optional positional
  /// parameters).
  final List<DecoratedType?>? positionalParameters;

  /// If `this` is a function type, the [DecoratedType] of each of its named
  /// parameters.
  final Map<String, DecoratedType?>? namedParameters;

  /// If `this` is a parameterized type, the [DecoratedType] of each of its
  /// type parameters.
  ///
  /// TODO(paulberry): how should we handle generic typedefs?
  final List<DecoratedType?> typeArguments;

  DecoratedType(this.type, this.node,
      {this.returnType,
      this.positionalParameters = const [],
      this.namedParameters = const {},
      this.typeArguments = const []}) {
    assert(() {
      assert(node != null);
      var type = this.type;
      if (type is InterfaceType) {
        assert(returnType == null);
        assert(positionalParameters!.isEmpty);
        assert(namedParameters!.isEmpty);
        assert(typeArguments.length == type.typeArguments.length);
        for (int i = 0; i < typeArguments.length; i++) {
          assert(typeArguments[i]!.type == type.typeArguments[i],
              '${typeArguments[i]!.type} != ${type.typeArguments[i]}');
        }
      } else if (type is FunctionType) {
        assert(returnType!.type == type.returnType);
        int positionalParameterCount = 0;
        int namedParameterCount = 0;
        for (var parameter in type.parameters) {
          if (parameter.isNamed) {
            assert(namedParameters![parameter.name]!.type == parameter.type);
            namedParameterCount++;
          } else {
            assert(positionalParameters![positionalParameterCount]!.type ==
                parameter.type);
            positionalParameterCount++;
          }
        }
        assert(positionalParameters!.length == positionalParameterCount);
        assert(namedParameters!.length == namedParameterCount);
        assert(typeArguments.isEmpty);
      } else if (node is TypeParameterType) {
        assert(returnType == null);
        assert(positionalParameters!.isEmpty);
        assert(namedParameters!.isEmpty);
        assert(typeArguments.isEmpty);
      } else {
        assert(returnType == null);
        assert(positionalParameters!.isEmpty);
        assert(namedParameters!.isEmpty);
        assert(typeArguments.isEmpty);
      }
      return true;
    }());
  }

  /// Creates a decorated type corresponding to [type], with fresh nullability
  /// nodes everywhere that don't correspond to any source location.  These
  /// nodes can later be unioned with other nodes.
  factory DecoratedType.forImplicitFunction(
      TypeProvider typeProvider,
      FunctionType type,
      NullabilityNode node,
      NullabilityGraph graph,
      NullabilityNodeTarget target,
      {DecoratedType? returnType}) {
    var positionalParameters = <DecoratedType>[];
    var namedParameters = <String, DecoratedType>{};
    int index = 0;
    for (var parameter in type.parameters) {
      if (parameter.isPositional) {
        positionalParameters.add(DecoratedType.forImplicitType(typeProvider,
            parameter.type, graph, target.positionalParameter(index++)));
      } else {
        var name = parameter.name;
        namedParameters[name] = DecoratedType.forImplicitType(
            typeProvider, parameter.type, graph, target.namedParameter(name));
      }
    }
    for (var element in type.typeFormals) {
      if (DecoratedTypeParameterBounds.current!.get(element) == null) {
        DecoratedTypeParameterBounds.current!.put(
            element,
            DecoratedType.forImplicitType(
                typeProvider,
                element.bound ?? typeProvider.objectType,
                graph,
                target.typeFormalBound(element.name)));
      }
    }
    return DecoratedType(type, node,
        returnType: returnType ??
            DecoratedType.forImplicitType(
                typeProvider, type.returnType, graph, target.returnType()),
        namedParameters: namedParameters,
        positionalParameters: positionalParameters);
  }

  /// Creates a DecoratedType corresponding to [type], with fresh nullability
  /// nodes everywhere that don't correspond to any source location.  These
  /// nodes can later be unioned with other nodes.
  factory DecoratedType.forImplicitType(TypeProvider typeProvider,
      DartType? type, NullabilityGraph graph, NullabilityNodeTarget target,
      {List<DecoratedType?>? typeArguments}) {
    var nullabilityNode = NullabilityNode.forInferredType(target);
    if (type is InterfaceType) {
      assert(() {
        if (typeArguments != null) {
          assert(typeArguments.length == type.typeArguments.length);
          for (var i = 0; i < typeArguments.length; ++i) {
            assert(typeArguments[i]!.type == type.typeArguments[i]);
          }
        }
        return true;
      }());

      int index = 0;
      typeArguments ??= type.typeArguments
          .map((t) => DecoratedType.forImplicitType(
              typeProvider, t, graph, target.typeArgument(index++)))
          .toList();
      return DecoratedType(type, nullabilityNode, typeArguments: typeArguments);
    } else if (type is FunctionType) {
      if (typeArguments != null) {
        throw 'Not supported: implicit function type with explicit type '
            'arguments';
      }
      return DecoratedType.forImplicitFunction(
          typeProvider, type, nullabilityNode, graph, target);
    } else {
      assert(typeArguments == null);
      return DecoratedType(type, nullabilityNode);
    }
  }

  /// Creates a [DecoratedType] for a synthetic type parameter, to be used
  /// during comparison of generic function types.
  DecoratedType._forTypeParameterSubstitution(TypeParameterElement parameter)
      : type = TypeParameterTypeImpl(
          element: parameter,
          nullabilitySuffix: NullabilitySuffix.star,
        ),
        node = null,
        returnType = null,
        positionalParameters = const [],
        namedParameters = const {},
        typeArguments = const [] {
    // We'll be storing the type parameter bounds in
    // [_decoratedTypeParameterBounds] so the type parameter needs to have an
    // enclosing element of `null`.
    assert(parameter.enclosingElement == null,
        '$parameter should not have parent ${parameter.enclosingElement}');
  }

  /// If `this` represents an interface type, returns the substitution necessary
  /// to produce this type using the class's type as a starting point.
  /// Otherwise throws an exception.
  ///
  /// For instance, if `this` represents `List<int?1>`, returns the substitution
  /// `{T: int?1}`, where `T` is the [TypeParameterElement] for `List`'s type
  /// parameter.
  Map<TypeParameterElement, DecoratedType?> get asSubstitution {
    var type = this.type;
    if (type is InterfaceType) {
      return Map<TypeParameterElement, DecoratedType?>.fromIterables(
          type.element.typeParameters, typeArguments);
    } else {
      throw StateError(
          'Tried to convert a non-interface type to a substitution');
    }
  }

  /// If this type is a function type, returns its generic formal parameters.
  /// Otherwise returns `null`.
  List<TypeParameterElement>? get typeFormals {
    var type = this.type;
    if (type is FunctionType) {
      return type.typeFormals;
    } else {
      return null;
    }
  }

  @override
  bool operator ==(Object other) {
    if (other is DecoratedType) {
      if (!identical(node, other.node)) return false;
      var thisType = type;
      var otherType = other.type;
      if (thisType is FunctionType && otherType is FunctionType) {
        if (thisType.normalParameterTypes.length !=
            otherType.normalParameterTypes.length) {
          return false;
        }
        if (thisType.typeFormals.length != otherType.typeFormals.length) {
          return false;
        }
        var renamed = RenamedDecoratedFunctionTypes.match(
            this, other, (bound1, bound2) => bound1 == bound2);
        if (renamed == null) return false;
        if (renamed.returnType1 != renamed.returnType2) return false;
        if (!_compareLists(
            renamed.positionalParameters1, renamed.positionalParameters2)) {
          return false;
        }
        if (!_compareMaps(renamed.namedParameters1, renamed.namedParameters2)) {
          return false;
        }
        return true;
      } else if (thisType is InterfaceType && otherType is InterfaceType) {
        if (thisType.element != otherType.element) return false;
        if (!_compareLists(typeArguments, other.typeArguments)) {
          return false;
        }
        return true;
      } else {
        return thisType == otherType;
      }
    }
    return false;
  }

  /// Converts one function type into another by substituting the given
  /// [argumentTypes] for the function's generic parameters.
  DecoratedType instantiate(List<DecoratedType> argumentTypes) {
    var type = this.type as FunctionType;
    var typeFormals = type.typeFormals;
    assert(argumentTypes.length == typeFormals.length);
    List<DartType> undecoratedArgumentTypes = [];
    Map<TypeParameterElement, DecoratedType> substitution = {};
    for (int i = 0; i < argumentTypes.length; i++) {
      var argumentType = argumentTypes[i];
      undecoratedArgumentTypes.add(argumentType.type!);
      substitution[typeFormals[i]] = argumentType;
    }
    return _substituteFunctionAfterFormals(
        type.instantiate(undecoratedArgumentTypes), substitution);
  }

  @override
  DecoratedTypeInfo? namedParameter(String name) => namedParameters![name];

  @override
  DecoratedTypeInfo? positionalParameter(int i) => positionalParameters![i];

  /// Updates the [roles] map with information about the nullability nodes
  /// pointed to by this decorated type.
  ///
  /// Each entry stored in [roles] maps the role of the node to the node itself.
  /// Roles look like pathnames, where each path component is an integer to
  /// represent a type argument (or a positional parameter type, in the case of
  /// a function type), an name to represent a named parameter type, or `@r` to
  /// represent a return type.
  void recordRoles(Map<String, NullabilityNode?> roles,
      {String rolePrefix = ''}) {
    roles[rolePrefix] = node;
    returnType?.recordRoles(roles, rolePrefix: '$rolePrefix/@r');
    for (int i = 0; i < positionalParameters!.length; i++) {
      positionalParameters![i]!
          .recordRoles(roles, rolePrefix: '$rolePrefix/$i');
    }
    for (var entry in namedParameters!.entries) {
      entry.value!.recordRoles(roles, rolePrefix: '$rolePrefix/${entry.key}');
    }
    for (int i = 0; i < typeArguments.length; i++) {
      typeArguments[i]!.recordRoles(roles, rolePrefix: '$rolePrefix/$i');
    }
  }

  /// Apply the given [substitution] to this type.
  ///
  /// [undecoratedResult] is the result of the substitution, as determined by
  /// the normal type system.  If not supplied, it is inferred.
  DecoratedType substitute(
      Map<TypeParameterElement, DecoratedType?> substitution,
      [DartType? undecoratedResult]) {
    if (substitution.isEmpty) return this;
    if (undecoratedResult == null) {
      var type = this.type!;
      undecoratedResult = Substitution.fromPairs(
        substitution.keys.toList(),
        substitution.values.map((d) => d!.type!).toList(),
      ).substituteType(type);
      if (undecoratedResult is FunctionType && type is FunctionType) {
        for (int i = 0; i < undecoratedResult.typeFormals.length; i++) {
          DecoratedTypeParameterBounds.current!.put(
              undecoratedResult.typeFormals[i],
              DecoratedTypeParameterBounds.current!.get(type.typeFormals[i]));
        }
      }
    }
    return _substitute(substitution, undecoratedResult);
  }

  @override
  String toString() {
    var trailing = node == null ? '' : node!.debugSuffix;
    var type = this.type;
    if (type is TypeParameterType || type is VoidType) {
      return '$type$trailing';
    } else if (type is InterfaceType) {
      var name = type.element.name;
      var args = '';
      if (type.typeArguments.isNotEmpty) {
        args = '<${typeArguments.join(', ')}>';
      }
      return '$name$args$trailing';
    } else if (type is FunctionType) {
      String formals = '';
      if (type.typeFormals.isNotEmpty) {
        formals = '<${type.typeFormals.join(', ')}>';
      }
      List<String> paramStrings = [];
      for (int i = 0; i < positionalParameters!.length; i++) {
        var prefix = '';
        if (i == type.normalParameterTypes.length) {
          prefix = '[';
        }
        paramStrings.add('$prefix${positionalParameters![i]}');
      }
      if (type.normalParameterTypes.length < positionalParameters!.length) {
        paramStrings.last += ']';
      }
      if (namedParameters!.isNotEmpty) {
        var prefix = '{';
        for (var entry in namedParameters!.entries) {
          paramStrings.add('$prefix${entry.key}: ${entry.value}');
          prefix = '';
        }
        paramStrings.last += '}';
      }
      var args = paramStrings.join(', ');
      return '$returnType Function$formals($args)$trailing';
    } else if (type is DynamicTypeImpl) {
      return 'dynamic';
    } else if (type!.isBottom) {
      return 'Never$trailing';
    } else {
      throw '$type'; // TODO(paulberry)
    }
  }

  @override
  DecoratedTypeInfo? typeArgument(int i) => typeArguments[i];

  /// Creates a shallow copy of `this`, replacing the nullability node.
  DecoratedType withNode(NullabilityNode? node) => DecoratedType(type, node,
      returnType: returnType,
      positionalParameters: positionalParameters,
      namedParameters: namedParameters,
      typeArguments: typeArguments);

  /// Creates a shallow copy of `this`, replacing the nullability node and the
  /// type.
  DecoratedType withNodeAndType(NullabilityNode node, DartType? type) =>
      DecoratedType(type, node,
          returnType: returnType,
          positionalParameters: positionalParameters,
          namedParameters: namedParameters,
          typeArguments: typeArguments);

  /// Internal implementation of [_substitute], used as a recursion target.
  DecoratedType _substitute(
      Map<TypeParameterElement, DecoratedType?> substitution,
      DartType? undecoratedResult) {
    var type = this.type;
    if (type is FunctionType && undecoratedResult is FunctionType) {
      var typeFormals = type.typeFormals;
      assert(typeFormals.length == undecoratedResult.typeFormals.length);
      if (typeFormals.isNotEmpty) {
        // The analyzer sometimes allocates fresh type variables when performing
        // substitutions, so we need to reflect that in our decorations by
        // substituting to use the type variables the analyzer used.
        substitution =
            Map<TypeParameterElement, DecoratedType>.from(substitution);
        for (int i = 0; i < typeFormals.length; i++) {
          // Check if it's a fresh type variable.
          if (undecoratedResult.typeFormals[i].enclosingElement == null) {
            substitution[typeFormals[i]] =
                DecoratedType._forTypeParameterSubstitution(
                    undecoratedResult.typeFormals[i]);
          }
        }
        for (int i = 0; i < typeFormals.length; i++) {
          var typeFormal = typeFormals[i];
          var oldDecoratedBound =
              DecoratedTypeParameterBounds.current!.get(typeFormal);
          var undecoratedResult2 = undecoratedResult.typeFormals[i].bound;
          if (undecoratedResult2 == null) {
            if (oldDecoratedBound == null) {
              assert(
                  false, 'Could not find old decorated bound for type formal');
              // Recover the best we can by assuming a bound of `dynamic`.
              oldDecoratedBound = DecoratedType(
                  DynamicTypeImpl.instance,
                  NullabilityNode.forInferredType(
                      NullabilityNodeTarget.text('Type parameter bound')));
            }
            undecoratedResult2 = oldDecoratedBound.type;
          }
          var newDecoratedBound =
              oldDecoratedBound!._substitute(substitution, undecoratedResult2);
          if (identical(typeFormal, undecoratedResult.typeFormals[i])) {
            assert(oldDecoratedBound == newDecoratedBound);
          } else {
            DecoratedTypeParameterBounds.current!
                .put(typeFormal, newDecoratedBound);
          }
        }
      }
      return _substituteFunctionAfterFormals(undecoratedResult, substitution);
    } else if (type is InterfaceType && undecoratedResult is InterfaceType) {
      List<DecoratedType> newTypeArguments = [];
      for (int i = 0; i < typeArguments.length; i++) {
        newTypeArguments.add(typeArguments[i]!
            .substitute(substitution, undecoratedResult.typeArguments[i]));
      }
      return DecoratedType(undecoratedResult, node,
          typeArguments: newTypeArguments);
    } else if (type is TypeParameterType) {
      var inner = substitution[type.element];
      if (inner == null) {
        return this;
      } else {
        return inner.withNodeAndType(
            NullabilityNode.forSubstitution(inner.node, node),
            undecoratedResult);
      }
    } else if (type!.isVoid || type.isDynamic) {
      return this;
    }
    throw '$type.substitute($type | $substitution)'; // TODO(paulberry)
  }

  /// Performs the logic that is common to substitution and function type
  /// instantiation.  Namely, a decorated type is formed whose undecorated type
  /// is [undecoratedResult], and whose return type, positional parameters, and
  /// named parameters are formed by performing the given [substitution].
  DecoratedType _substituteFunctionAfterFormals(FunctionType undecoratedResult,
      Map<TypeParameterElement, DecoratedType?> substitution) {
    var newPositionalParameters = <DecoratedType>[];
    var numRequiredParameters = undecoratedResult.normalParameterTypes.length;
    for (int i = 0; i < positionalParameters!.length; i++) {
      var undecoratedParameterType = i < numRequiredParameters
          ? undecoratedResult.normalParameterTypes[i]
          : undecoratedResult.optionalParameterTypes[i - numRequiredParameters];
      newPositionalParameters.add(positionalParameters![i]!
          ._substitute(substitution, undecoratedParameterType));
    }
    var newNamedParameters = <String, DecoratedType>{};
    for (var entry in namedParameters!.entries) {
      var name = entry.key;
      var undecoratedParameterType =
          undecoratedResult.namedParameterTypes[name];
      newNamedParameters[name] =
          (entry.value!._substitute(substitution, undecoratedParameterType));
    }
    return DecoratedType(undecoratedResult, node,
        returnType:
            returnType!._substitute(substitution, undecoratedResult.returnType),
        positionalParameters: newPositionalParameters,
        namedParameters: newNamedParameters);
  }

  static bool _compareLists(
      List<DecoratedType?>? list1, List<DecoratedType?>? list2) {
    if (identical(list1, list2)) return true;
    if (list1!.length != list2!.length) return false;
    for (int i = 0; i < list1.length; i++) {
      if (list1[i] != list2[i]) return false;
    }
    return true;
  }

  static bool _compareMaps(
      Map<String, DecoratedType?>? map1, Map<String, DecoratedType?>? map2) {
    if (identical(map1, map2)) return true;
    if (map1!.length != map2!.length) return false;
    for (var entry in map1.entries) {
      if (entry.value != map2[entry.key]) return false;
    }
    return true;
  }
}

/// Data structure mapping type parameters to their decorated bounds.
///
/// Since we need to be able to access this mapping globally throughout the
/// migration engine, from places where we can't easily inject it, the current
/// mapping is stored in a static variable.
class DecoratedTypeParameterBounds {
  /// The [DecoratedTypeParameterBounds] currently in use, or `null` if we are
  /// not currently in a stage of migration where we need access to the
  /// decorated types of type parameter bounds.
  ///
  /// If `null`, then attempts to look up the decorated types of type parameter
  /// bounds will fail.
  static DecoratedTypeParameterBounds? current;

  final _orphanBounds = Expando<DecoratedType>();

  final _parentedBounds = <TypeParameterElement, DecoratedType?>{};

  DecoratedType? get(TypeParameterElement element) {
    if (element.enclosingElement == null) {
      return _orphanBounds[element];
    } else {
      return _parentedBounds[element];
    }
  }

  void put(TypeParameterElement element, DecoratedType? bounds) {
    if (element.enclosingElement == null) {
      _orphanBounds[element] = bounds;
    } else {
      _parentedBounds[element] = bounds;
    }
  }
}

/// Helper class that renames the type parameters in two decorated function
/// types so that they match.
class RenamedDecoratedFunctionTypes {
  final DecoratedType? returnType1;

  final DecoratedType? returnType2;

  final List<DecoratedType?>? positionalParameters1;

  final List<DecoratedType?>? positionalParameters2;

  final Map<String, DecoratedType?>? namedParameters1;

  final Map<String, DecoratedType?>? namedParameters2;

  RenamedDecoratedFunctionTypes._(
      this.returnType1,
      this.returnType2,
      this.positionalParameters1,
      this.positionalParameters2,
      this.namedParameters1,
      this.namedParameters2);

  /// Attempt to find a renaming of the type parameters of [type1] and [type2]
  /// (both of which should be function types) such that the generic type
  /// parameters match.
  ///
  /// The callback [boundsMatcher] is used to determine whether type parameter
  /// bounds match.
  ///
  /// If such a renaming can be found, it is returned.  If not, `null` is
  /// returned.
  static RenamedDecoratedFunctionTypes? match(
      DecoratedType type1,
      DecoratedType type2,
      bool Function(DecoratedType, DecoratedType) boundsMatcher) {
    if (!_isNeeded(type1.typeFormals, type2.typeFormals)) {
      return RenamedDecoratedFunctionTypes._(
          type1.returnType,
          type2.returnType,
          type1.positionalParameters,
          type2.positionalParameters,
          type1.namedParameters,
          type2.namedParameters);
    }
    // Create a fresh set of type variables and substitute so we can
    // compare safely.
    var substitution1 = <TypeParameterElement, DecoratedType>{};
    var substitution2 = <TypeParameterElement, DecoratedType>{};
    var newParameters = <TypeParameterElement>[];
    for (int i = 0; i < type1.typeFormals!.length; i++) {
      var newParameter =
          TypeParameterElementImpl.synthetic(type1.typeFormals![i].name);
      newParameters.add(newParameter);
      var newParameterType =
          DecoratedType._forTypeParameterSubstitution(newParameter);
      substitution1[type1.typeFormals![i]] = newParameterType;
      substitution2[type2.typeFormals![i]] = newParameterType;
    }
    for (int i = 0; i < type1.typeFormals!.length; i++) {
      var bound1 = DecoratedTypeParameterBounds.current!
          .get((type1.type as FunctionType).typeFormals[i])!
          .substitute(substitution1);
      var bound2 = DecoratedTypeParameterBounds.current!
          .get((type2.type as FunctionType).typeFormals[i])!
          .substitute(substitution2);
      if (!boundsMatcher(bound1, bound2)) return null;
      DecoratedTypeParameterBounds.current!.put(newParameters[i], bound1);
    }
    var returnType1 = type1.returnType!.substitute(substitution1);
    var returnType2 = type2.returnType!.substitute(substitution2);
    var positionalParameters1 =
        _substituteList(type1.positionalParameters!, substitution1);
    var positionalParameters2 =
        _substituteList(type2.positionalParameters!, substitution2);
    var namedParameters1 =
        _substituteMap(type1.namedParameters!, substitution1);
    var namedParameters2 =
        _substituteMap(type2.namedParameters!, substitution2);
    return RenamedDecoratedFunctionTypes._(
        returnType1,
        returnType2,
        positionalParameters1,
        positionalParameters2,
        namedParameters1,
        namedParameters2);
  }

  static bool _isNeeded(List<TypeParameterElement>? formals1,
      List<TypeParameterElement>? formals2) {
    if (identical(formals1, formals2)) return false;
    if (formals1!.length != formals2!.length) return true;
    for (int i = 0; i < formals1.length; i++) {
      if (!identical(formals1[i], formals2[i])) return true;
    }
    return false;
  }

  static List<DecoratedType> _substituteList(List<DecoratedType?> list,
      Map<TypeParameterElement, DecoratedType> substitution) {
    return list.map((t) => t!.substitute(substitution)).toList();
  }

  static Map<String, DecoratedType> _substituteMap(
      Map<String, DecoratedType?> map,
      Map<TypeParameterElement, DecoratedType> substitution) {
    var result = <String, DecoratedType>{};
    for (var entry in map.entries) {
      result[entry.key] = entry.value!.substitute(substitution);
    }
    return result;
  }
}
