// 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 newDecoratedBound = oldDecoratedBound._substitute(substitution,
              undecoratedResult.typeFormals[i].bound ?? oldDecoratedBound.type);
          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;
  }
}
