// 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_visitor.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/extensions.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_schema.dart';
import 'package:analyzer/src/dart/element/type_visitor.dart';
import 'package:analyzer/src/summary2/function_type_builder.dart';
import 'package:analyzer/src/summary2/named_type_builder.dart';

/// Generates a fresh copy of the given type parameters, with their bounds
/// substituted to reference the new parameters.
///
/// The returned object contains the fresh type parameter list as well as a
/// mapping to be used for replacing other types to use the new type parameters.
FreshTypeParameters getFreshTypeParameters(
    List<TypeParameterElement> typeParameters) {
  var freshParameters = List<TypeParameterElementImpl>.generate(
    typeParameters.length,
    (i) => TypeParameterElementImpl(typeParameters[i].name, -1),
    growable: true,
  );

  var map = <TypeParameterElement, DartType>{};
  for (int i = 0; i < typeParameters.length; ++i) {
    map[typeParameters[i]] = TypeParameterTypeImpl(
      element: freshParameters[i],
      nullabilitySuffix: NullabilitySuffix.none,
    );
  }

  var substitution = Substitution.fromMap(map);

  for (int i = 0; i < typeParameters.length; ++i) {
    // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
    // variance is added to the interface.
    var typeParameter = typeParameters[i] as TypeParameterElementImpl;
    if (!typeParameter.isLegacyCovariant) {
      freshParameters[i].variance = typeParameter.variance;
    }

    var bound = typeParameter.bound;
    if (bound != null) {
      var newBound = substitution.substituteType(bound);
      freshParameters[i].bound = newBound;
    }
  }

  return FreshTypeParameters(freshParameters, substitution);
}

/// Given a generic function [type] of a class member (so that it does not
/// carry its element and type arguments), substitute its type parameters with
/// the [newTypeParameters] in the formal parameters and return type.
FunctionType replaceTypeParameters(
  FunctionTypeImpl type,
  List<TypeParameterElement> newTypeParameters,
) {
  assert(newTypeParameters.length == type.typeFormals.length);
  if (newTypeParameters.isEmpty) {
    return type;
  }

  var typeArguments = newTypeParameters
      .map((e) => e.instantiate(nullabilitySuffix: NullabilitySuffix.none))
      .toList();
  var substitution = Substitution.fromPairs(type.typeFormals, typeArguments);

  ParameterElement transformParameter(ParameterElement p) {
    var type = substitution.substituteType(p.type);
    return p.copyWith(type: type);
  }

  return FunctionTypeImpl(
    typeFormals: newTypeParameters,
    parameters: type.parameters.map(transformParameter).toList(),
    returnType: substitution.substituteType(type.returnType),
    nullabilitySuffix: type.nullabilitySuffix,
  );
}

/// Returns a type where all occurrences of the given type parameters have been
/// replaced with the corresponding types.
///
/// This will copy only the sub-terms of [type] that contain substituted
/// variables; all other [DartType] objects will be reused.
///
/// In particular, if no type parameters were substituted, this is guaranteed
/// to return the [type] instance (not a copy), so the caller may use
/// [identical] to efficiently check if a distinct type was created.
DartType substitute(
  DartType type,
  Map<TypeParameterElement, DartType> substitution,
) {
  if (substitution.isEmpty) {
    return type;
  }
  return Substitution.fromMap(substitution).substituteType(type);
}

class FreshTypeParameters {
  final List<TypeParameterElement> freshTypeParameters;
  final Substitution substitution;

  FreshTypeParameters(this.freshTypeParameters, this.substitution);

  FunctionType applyToFunctionType(FunctionType type) {
    return FunctionTypeImpl(
      typeFormals: freshTypeParameters,
      parameters: type.parameters.map((parameter) {
        var type = substitute(parameter.type);
        return parameter.copyWith(type: type);
      }).toList(),
      returnType: substitute(type.returnType),
      nullabilitySuffix: type.nullabilitySuffix,
    );
  }

  DartType substitute(DartType type) => substitution.substituteType(type);
}

/// Substitution that is based on the [map].
abstract class MapSubstitution extends Substitution {
  const MapSubstitution();

  Map<TypeParameterElement, DartType> get map;
}

abstract class Substitution {
  static const MapSubstitution empty = _NullSubstitution.instance;

  const Substitution();

  DartType getSubstitute(TypeParameterElement parameter, bool upperBound);

  DartType substituteType(DartType type, {bool contravariant = false}) {
    var visitor = _TopSubstitutor(this, contravariant);
    return type.accept(visitor);
  }

  /// Substitutes both variables from [first] and [second], favoring those from
  /// [first] if they overlap.
  ///
  /// Neither substitution is applied to the results of the other, so this does
  /// *not* correspond to a sequence of two substitutions. For example,
  /// combining `{T -> List<G>}` with `{G -> String}` does not correspond to
  /// `{T -> List<String>}` because the result from substituting `T` is not
  /// searched for occurrences of `G`.
  static Substitution combine(Substitution first, Substitution second) {
    if (first == _NullSubstitution.instance) return second;
    if (second == _NullSubstitution.instance) return first;
    return _CombinedSubstitution(first, second);
  }

  /// Substitutes the type parameters on the class of [type] with the
  /// type arguments provided in [type].
  static Substitution fromInterfaceType(InterfaceType type) {
    if (type.typeArguments.isEmpty) {
      return _NullSubstitution.instance;
    }
    return fromPairs(type.element.typeParameters, type.typeArguments);
  }

  /// Substitutes each parameter to the type it maps to in [map].
  static MapSubstitution fromMap(Map<TypeParameterElement, DartType> map) {
    if (map.isEmpty) {
      return _NullSubstitution.instance;
    }
    return _MapSubstitution(map);
  }

  /// Substitutes the Nth parameter in [parameters] with the Nth type in
  /// [types].
  static MapSubstitution fromPairs(
    List<TypeParameterElement> parameters,
    List<DartType> types,
  ) {
    assert(parameters.length == types.length);
    if (parameters.isEmpty) {
      return _NullSubstitution.instance;
    }
    return fromMap(
      Map<TypeParameterElement, DartType>.fromIterables(
        parameters,
        types,
      ),
    );
  }

  /// Substitutes all occurrences of the given type parameters with the
  /// corresponding upper or lower bound, depending on the variance of the
  /// context where it occurs.
  ///
  /// For example the type `(T) => T` with the bounds `bottom <: T <: num`
  /// becomes `(bottom) => num` (in this example, `num` is the upper bound,
  /// and `bottom` is the lower bound).
  ///
  /// This is a way to obtain an upper bound for a type while eliminating all
  /// references to certain type variables.
  static Substitution fromUpperAndLowerBounds(
    Map<TypeParameterElement, DartType> upper,
    Map<TypeParameterElement, DartType> lower,
  ) {
    if (upper.isEmpty && lower.isEmpty) {
      return _NullSubstitution.instance;
    }
    return _UpperLowerBoundsSubstitution(upper, lower);
  }
}

class _CombinedSubstitution extends Substitution {
  final Substitution first;
  final Substitution second;

  _CombinedSubstitution(this.first, this.second);

  @override
  DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
    return first.getSubstitute(parameter, upperBound) ??
        second.getSubstitute(parameter, upperBound);
  }
}

class _FreshTypeParametersSubstitutor extends _TypeSubstitutor {
  final Map<TypeParameterElement, DartType> substitution = {};

  _FreshTypeParametersSubstitutor(_TypeSubstitutor outer) : super(outer);

  @override
  List<TypeParameterElement> freshTypeParameters(
      List<TypeParameterElement> elements) {
    if (elements.isEmpty) {
      return const <TypeParameterElement>[];
    }

    var freshElements = List<TypeParameterElement>(elements.length);
    for (var i = 0; i < elements.length; i++) {
      // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
      // variance is added to the interface.
      var element = elements[i] as TypeParameterElementImpl;
      var freshElement = TypeParameterElementImpl(element.name, -1);
      freshElements[i] = freshElement;
      var freshType = freshElement.instantiate(
        nullabilitySuffix: NullabilitySuffix.none,
      );
      freshElement.type = freshType;
      substitution[element] = freshType;

      if (!element.isLegacyCovariant) {
        freshElement.variance = element.variance;
      }
    }

    for (var i = 0; i < freshElements.length; i++) {
      var element = elements[i];
      if (element.bound != null) {
        TypeParameterElementImpl freshElement = freshElements[i];
        freshElement.bound = element.bound.accept(this);
      }
    }

    return freshElements;
  }

  @override
  DartType lookup(TypeParameterElement parameter, bool upperBound) {
    return substitution[parameter];
  }
}

class _MapSubstitution extends MapSubstitution {
  @override
  final Map<TypeParameterElement, DartType> map;

  _MapSubstitution(this.map);

  @override
  DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
    return map[parameter];
  }

  @override
  String toString() => '_MapSubstitution($map)';
}

class _NullSubstitution extends MapSubstitution {
  static const _NullSubstitution instance = _NullSubstitution();

  const _NullSubstitution();

  @override
  Map<TypeParameterElement, DartType> get map => const {};

  @override
  DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
    return TypeParameterTypeImpl(
      element: parameter,
      nullabilitySuffix: NullabilitySuffix.star,
    );
  }

  @override
  DartType substituteType(DartType type, {bool contravariant = false}) => type;

  @override
  String toString() => "Substitution.empty";
}

class _TopSubstitutor extends _TypeSubstitutor {
  final Substitution substitution;

  _TopSubstitutor(this.substitution, bool contravariant) : super(null) {
    if (contravariant) {
      invertVariance();
    }
  }

  @override
  List<TypeParameterElement> freshTypeParameters(
      List<TypeParameterElement> parameters) {
    throw 'Create a fresh environment first';
  }

  @override
  DartType lookup(TypeParameterElement parameter, bool upperBound) {
    return substitution.getSubstitute(parameter, upperBound);
  }
}

abstract class _TypeSubstitutor
    implements
        TypeVisitor<DartType>,
        InferenceTypeVisitor<DartType>,
        LinkingTypeVisitor<DartType> {
  final _TypeSubstitutor outer;
  bool covariantContext = true;

  /// The number of times a variable from this environment has been used in
  /// a substitution.
  ///
  /// There is a strict requirement that we must return the same instance for
  /// types that were not altered by the substitution.  This counter lets us
  /// check quickly if anything happened in a substitution.
  int useCounter = 0;

  _TypeSubstitutor(this.outer) {
    covariantContext = outer == null ? true : outer.covariantContext;
  }

  void bumpCountersUntil(_TypeSubstitutor target) {
    var substitutor = this;
    while (substitutor != target) {
      substitutor.useCounter++;
      substitutor = substitutor.outer;
    }
    target.useCounter++;
  }

  List<TypeParameterElement> freshTypeParameters(
      List<TypeParameterElement> elements);

  DartType getSubstitute(TypeParameterElement parameter) {
    var environment = this;
    while (environment != null) {
      var replacement = environment.lookup(parameter, covariantContext);
      if (replacement != null) {
        bumpCountersUntil(environment);
        return replacement;
      }
      environment = environment.outer;
    }
    return null;
  }

  void invertVariance() {
    covariantContext = !covariantContext;
  }

  DartType lookup(TypeParameterElement parameter, bool upperBound);

  _FreshTypeParametersSubstitutor newInnerEnvironment() {
    return _FreshTypeParametersSubstitutor(this);
  }

  @override
  DartType visitDynamicType(DynamicType type) => type;

  @override
  DartType visitFunctionType(FunctionType type) {
    // This is a bit tricky because we have to generate fresh type parameters
    // in order to change the bounds.  At the same time, if the function type
    // was unaltered, we have to return the [type] object (not a copy!).
    // Substituting a type for a fresh type variable should not be confused
    // with a "real" substitution.
    //
    // Create an inner environment to generate fresh type parameters.  The use
    // counter on the inner environment tells if the fresh type parameters have
    // any uses, but does not tell if the resulting function type is distinct.
    // Our own use counter will get incremented if something from our
    // environment has been used inside the function.
    int before = useCounter;

    var inner = this;
    var typeFormals = type.typeFormals;
    if (typeFormals.isNotEmpty) {
      inner = newInnerEnvironment();
      typeFormals = inner.freshTypeParameters(typeFormals);
    }

    // Invert the variance when translating parameters.
    inner.invertVariance();

    var parameters = type.parameters.map((parameter) {
      var type = parameter.type.accept(inner);
      return parameter.copyWith(type: type);
    }).toList();

    inner.invertVariance();

    var returnType = type.returnType.accept(inner);
    var typeArguments = _mapList(type.typeArguments);

    if (useCounter == before) return type;

    return FunctionTypeImpl(
      typeFormals: typeFormals,
      parameters: parameters,
      returnType: returnType,
      nullabilitySuffix: type.nullabilitySuffix,
      element: type.element,
      typeArguments: typeArguments,
    );
  }

  @override
  DartType visitFunctionTypeBuilder(FunctionTypeBuilder type) {
    // This is a bit tricky because we have to generate fresh type parameters
    // in order to change the bounds.  At the same time, if the function type
    // was unaltered, we have to return the [type] object (not a copy!).
    // Substituting a type for a fresh type variable should not be confused
    // with a "real" substitution.
    //
    // Create an inner environment to generate fresh type parameters.  The use
    // counter on the inner environment tells if the fresh type parameters have
    // any uses, but does not tell if the resulting function type is distinct.
    // Our own use counter will get incremented if something from our
    // environment has been used inside the function.
    int before = useCounter;

    var inner = this;
    var typeFormals = type.typeFormals;
    if (typeFormals.isNotEmpty) {
      inner = newInnerEnvironment();
      typeFormals = inner.freshTypeParameters(typeFormals);
    }

    // Invert the variance when translating parameters.
    inner.invertVariance();

    var parameters = type.parameters.map((parameter) {
      var type = parameter.type.accept(inner);
      return parameter.copyWith(type: type);
    }).toList();

    inner.invertVariance();

    var returnType = type.returnType.accept(inner);

    if (useCounter == before) return type;

    return FunctionTypeBuilder(
      typeFormals,
      parameters,
      returnType,
      type.nullabilitySuffix,
    );
  }

  @override
  DartType visitInterfaceType(InterfaceType type) {
    if (type.typeArguments.isEmpty) {
      return type;
    }

    int before = useCounter;
    var typeArguments = _mapList(type.typeArguments);
    if (useCounter == before) {
      return type;
    }

    return InterfaceTypeImpl(
      element: type.element,
      typeArguments: typeArguments,
      nullabilitySuffix: type.nullabilitySuffix,
    );
  }

  @override
  DartType visitNamedTypeBuilder(NamedTypeBuilder type) {
    if (type.arguments.isEmpty) {
      return type;
    }

    int before = useCounter;
    var arguments = _mapList(type.arguments);
    if (useCounter == before) {
      return type;
    }

    return NamedTypeBuilder(
      type.typeSystem,
      type.element,
      arguments,
      type.nullabilitySuffix,
    );
  }

  @override
  DartType visitNeverType(NeverType type) => type;

  @override
  DartType visitTypeParameterType(TypeParameterType type) {
    var argument = getSubstitute(type.element);
    if (argument == null) {
      return type;
    }

    var parameterSuffix = type.nullabilitySuffix;
    var argumentSuffix = argument.nullabilitySuffix;
    var nullability = _computeNullability(parameterSuffix, argumentSuffix);
    return (argument as TypeImpl).withNullability(nullability);
  }

  @override
  DartType visitUnknownInferredType(UnknownInferredType type) => type;

  @override
  DartType visitVoidType(VoidType type) => type;

  List<DartType> _mapList(List<DartType> types) {
    return types.map((e) => e.accept(this)).toList();
  }

  ///  1. Substituting T=X! into T! yields X!
  ///  2. Substituting T=X* into T! yields X*
  ///  3. Substituting T=X? into T! yields X?
  ///  4. Substituting T=X! into T* yields X*
  ///  5. Substituting T=X* into T* yields X*
  ///  6. Substituting T=X? into T* yields X?
  ///  7. Substituting T=X! into T? yields X?
  ///  8. Substituting T=X* into T? yields X?
  ///  9. Substituting T=X? into T? yields X?
  static NullabilitySuffix _computeNullability(
    NullabilitySuffix parameterSuffix,
    NullabilitySuffix argumentSuffix,
  ) {
    if (parameterSuffix == NullabilitySuffix.question ||
        argumentSuffix == NullabilitySuffix.question) {
      return NullabilitySuffix.question;
    }
    if (parameterSuffix == NullabilitySuffix.star ||
        argumentSuffix == NullabilitySuffix.star) {
      return NullabilitySuffix.star;
    }
    return NullabilitySuffix.none;
  }
}

class _UpperLowerBoundsSubstitution extends Substitution {
  final Map<TypeParameterElement, DartType> upper;
  final Map<TypeParameterElement, DartType> lower;

  _UpperLowerBoundsSubstitution(this.upper, this.lower);

  @override
  DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
    return upperBound ? upper[parameter] : lower[parameter];
  }

  @override
  String toString() => '_UpperLowerBoundsSubstitution($upper, $lower)';
}
