package org.checkerframework.framework.util;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Types;
import org.checkerframework.javacutil.Pair;

/**
 * Records any mapping between the type parameters of a subtype to the corresponding type parameters
 * of a supertype. For example, suppose we have the following classes:
 *
 * <pre>{@code
 * class Map<M1,M2>
 * class HashMap<H1, H2> extends Map<H1,H2>
 * }</pre>
 *
 * And we pass HashMap and Map to mapTypeArguments, the result would be:
 *
 * <pre>{@code
 * Map(H1 => M1, H2 => M2)
 * }</pre>
 *
 * Note, a single type argument in the subtype can map to multiple type parameters in the supertype.
 * e.g.,
 *
 * <pre>{@code
 * class OneTypeMap<O1> extends Map<O1,O1>
 * }</pre>
 *
 * would have the result:
 *
 * <pre>{@code
 * Map(O1 => [M1,M2])
 * }</pre>
 *
 * This utility only maps between corresponding type parameters, so the following class:
 *
 * <pre>{@code
 * class StringMap extends Map<String,String>
 * }</pre>
 *
 * would have an empty map as a result:
 *
 * <pre>{@code
 * Map() // there are no type argument relationships between the two types
 * }</pre>
 */
public class TypeArgumentMapper {

  /**
   * Returns a mapping from subtype's type parameter indices to the indices of corresponding type
   * parameters in supertype.
   */
  public static Set<Pair<Integer, Integer>> mapTypeArgumentIndices(
      final TypeElement subtype, final TypeElement supertype, final Types types) {
    Set<Pair<Integer, Integer>> result = new HashSet<>();
    if (subtype.equals(supertype)) {
      for (int i = 0; i < subtype.getTypeParameters().size(); i++) {
        result.add(Pair.of(Integer.valueOf(i), Integer.valueOf(i)));
      }

    } else {
      Map<TypeParameterElement, Set<TypeParameterElement>> subToSuperElements =
          mapTypeArguments(subtype, supertype, types);
      Map<TypeParameterElement, Integer> supertypeIndexes = getElementToIndex(supertype);

      final List<? extends TypeParameterElement> subtypeParams = subtype.getTypeParameters();
      for (int subtypeIndex = 0; subtypeIndex < subtypeParams.size(); subtypeIndex++) {
        final TypeParameterElement subtypeParam = subtypeParams.get(subtypeIndex);

        final Set<TypeParameterElement> correspondingSuperArgs =
            subToSuperElements.get(subtypeParam);
        if (correspondingSuperArgs != null) {
          for (TypeParameterElement supertypeParam : subToSuperElements.get(subtypeParam)) {
            result.add(Pair.of(subtypeIndex, supertypeIndexes.get(supertypeParam)));
          }
        }
      }
    }

    return result;
  }

  /**
   * Returns a Map(type parameter symbol &rarr; index in type parameter list).
   *
   * @param typeElement a type whose type parameters to summarize
   * @return a Map(type parameter symbol &rarr; index in type parameter list)
   */
  private static Map<TypeParameterElement, Integer> getElementToIndex(TypeElement typeElement) {
    Map<TypeParameterElement, Integer> result = new LinkedHashMap<>();

    List<? extends TypeParameterElement> params = typeElement.getTypeParameters();
    for (int i = 0; i < params.size(); i++) {
      result.put(params.get(i), Integer.valueOf(i));
    }

    return result;
  }

  /**
   * Returns a mapping from the type parameters of subtype to a list of the type parameters in
   * supertype that must be the same type as subtype.
   *
   * <p>e.g.,
   *
   * <pre>{@code
   * class A<A1,A2,A3>
   * class B<B1,B2,B3,B4> extends A<B1,B1,B3> {}
   * }</pre>
   *
   * results in a {@code Map(B1 => [A1,A2], B2 => [], B3 => [A3], B4 => [])}
   *
   * @return a mapping from the type parameters of subtype to the supertype type parameter's that to
   *     which they are a type argument
   */
  public static Map<TypeParameterElement, Set<TypeParameterElement>> mapTypeArguments(
      final TypeElement subtype, final TypeElement supertype, final Types types) {

    final List<TypeRecord> pathToSupertype =
        depthFirstSearchForSupertype(subtype, supertype, types);

    if (pathToSupertype == null || pathToSupertype.isEmpty()) {
      return new LinkedHashMap<>();
    }

    final Map<TypeParameterElement, Set<TypeParameterElement>> intermediate = new LinkedHashMap<>();
    final Set<TypeParameterElement> currentTypeParams = new HashSet<>();

    // takes a type records of the form:
    //  TypeRecord(element = MyMap<Y1,Y2>, type = null)
    //  TypeRecord(element = AbstractMap<A1,A2>, type = AbstractMap<Y1,Y2>)
    //  TypeRecord(element = Map<M1,M2>, type = AbstractMap<A1,A2>)
    // And makes a map:
    //   Map(Y1 -> [A1], Y2 -> [A2], A1 -> [M1], A2 -> M2]
    Iterator<TypeRecord> path = pathToSupertype.iterator();
    TypeRecord current = path.next();
    while (path.hasNext()) {
      TypeRecord next = path.next();

      final List<? extends TypeParameterElement> nextTypeParameter =
          next.element.getTypeParameters();
      final List<? extends TypeMirror> nextTypeArgs =
          next.type != null ? next.type.getTypeArguments() : Collections.emptyList();
      currentTypeParams.clear();
      currentTypeParams.addAll(current.element.getTypeParameters());

      for (int i = 0; i < nextTypeArgs.size(); i++) {
        final TypeParameterElement correspondingParameter = nextTypeParameter.get(i);
        final TypeMirror typeArg = nextTypeArgs.get(i);
        final Element typeArgEle = types.asElement(typeArg);

        if (currentTypeParams.contains(typeArgEle)) {
          addToSetMap(intermediate, (TypeParameterElement) typeArgEle, correspondingParameter);
        }
      }
    }

    List<? extends TypeParameterElement> supertypeParams = supertype.getTypeParameters();
    final Map<TypeParameterElement, Set<TypeParameterElement>> result =
        new LinkedHashMap<>(subtype.getTypeParameters().size());

    // You can think of the map above as a set of links from SubtypeParameter -> Supertype Parameter
    for (TypeParameterElement subtypeParam : subtype.getTypeParameters()) {
      Set<TypeParameterElement> subtypePath =
          flattenPath(intermediate.get(subtypeParam), intermediate);
      subtypePath.retainAll(supertypeParams);
      result.put(subtypeParam, subtypePath);
    }

    return result;
  }

  private static Set<TypeParameterElement> flattenPath(
      Set<TypeParameterElement> elements,
      Map<TypeParameterElement, Set<TypeParameterElement>> map) {
    Set<TypeParameterElement> result = new HashSet<>();
    if (elements == null) {
      return result;
    }
    for (final TypeParameterElement oldElement : elements) {
      Set<TypeParameterElement> substitutions = map.get(oldElement);
      if (substitutions != null) {
        result.addAll(flattenPath(elements, map));
      } else {
        result.add(oldElement);
      }
    }
    return result;
  }

  private static void addToSetMap(
      final Map<TypeParameterElement, Set<TypeParameterElement>> setMap,
      final TypeParameterElement element,
      final TypeParameterElement typeParam) {
    Set<TypeParameterElement> set = setMap.computeIfAbsent(element, __ -> new HashSet<>());
    set.add(typeParam);
  }

  /**
   * Create a list of TypeRecord's that form a "path" to target from subtype. e.g. Suppose I have
   * the types
   *
   * <pre>{@code
   * interface Map<M1,M2>
   * class AbstractMap<A1,A2> implements Map<A1,A2>, Iterable<Map.Entry<M1,M2>>
   * class MyMap<Y1,Y2> extends AbstractMap<Y1,Y2> implements List<Map.Entry<Y1,Y2>>
   * }</pre>
   *
   * The path from MyMap to Map would be:
   *
   * <pre>{@code
   * TypeRecord(element = MyMap<Y1,Y2>, type = null)
   * TypeRecord(element = AbstractMap<A1,A2>, type = AbstractMap<Y1,Y2>)
   * TypeRecord(element = Map<M1,M2>, type = AbstractMap<A1,A2>)
   * }</pre>
   *
   * Note: You can have an implementation of the same interface inherited multiple times as long as
   * the parameterization of that interface remains the same e.g.
   *
   * <pre>{@code
   * interface List<E>
   * class AbstractList<A> implements List<E>
   * class ArrayList<T> extends AbstractList<T> implements List<T>
   * }</pre>
   *
   * Notice how ArrayList implements list both by inheriting from AbstractList and from explicitly
   * listing it in the implements clause. We prioritize finding a path through the list of
   * interfaces first since this will be the shorter path.
   *
   * @param subtype the start of the resulting sequence
   * @param target the end of the resulting sequence
   * @param types utility methods for operating on types
   * @return a list of type records that represents the sequence of directSupertypes between subtype
   *     and target
   */
  private static List<TypeRecord> depthFirstSearchForSupertype(
      final TypeElement subtype, final TypeElement target, final Types types) {
    ArrayDeque<TypeRecord> pathFromRoot = new ArrayDeque<>();
    final TypeRecord pathStart = new TypeRecord(subtype, null);
    pathFromRoot.push(pathStart);
    final List<TypeRecord> result = recursiveDepthFirstSearch(pathFromRoot, target, types);
    return result;
  }

  /**
   * Computes one level for depthFirstSearchForSupertype then recurses.
   *
   * @param pathFromRoot the path so far
   * @param target the end of the resulting path
   * @param types utility methods for operating on types
   * @return a list of type records that extends pathFromRoot (a sequence of directSupertypes) to
   *     target
   */
  private static List<TypeRecord> recursiveDepthFirstSearch(
      final ArrayDeque<TypeRecord> pathFromRoot, final TypeElement target, final Types types) {
    if (pathFromRoot.isEmpty()) {
      return null;
    }

    final TypeRecord currentRecord = pathFromRoot.peekLast();
    final TypeElement currentElement = currentRecord.element;

    if (currentElement.equals(target)) {
      return new ArrayList<>(pathFromRoot);
    }

    final Iterator<? extends TypeMirror> interfaces = currentElement.getInterfaces().iterator();
    final TypeMirror superclassType = currentElement.getSuperclass();

    List<TypeRecord> path = null;

    while (path == null && interfaces.hasNext()) {
      final TypeMirror intface = interfaces.next();
      if (intface.getKind() != TypeKind.NONE) {
        DeclaredType interfaceDeclared = (DeclaredType) intface;
        pathFromRoot.addLast(
            new TypeRecord((TypeElement) types.asElement(interfaceDeclared), interfaceDeclared));
        path = recursiveDepthFirstSearch(pathFromRoot, target, types);
        pathFromRoot.removeLast();
      }
    }

    if (path == null && superclassType.getKind() != TypeKind.NONE) {
      final DeclaredType superclass = (DeclaredType) superclassType;

      pathFromRoot.addLast(new TypeRecord((TypeElement) types.asElement(superclass), superclass));
      path = recursiveDepthFirstSearch(pathFromRoot, target, types);
      pathFromRoot.removeLast();
    }

    return path;
  }

  /**
   * Maps a class or interface's declaration element to the type it would be if viewed from a
   * subtype class or interface.
   *
   * <p>e.g. suppose we have the elements for the declarations:
   *
   * <pre>{@code
   * class A<Ta>
   * class B<Tb> extends A<Tb>
   * }</pre>
   *
   * The type record of B if it is viewed as class A would bed:
   *
   * <pre>{@code
   * TypeRecord( element = A<Ta>, type = A<Tb> )
   * }</pre>
   *
   * That is, B can be viewed as an object of type A with an type argument of type parameter Tb
   */
  private static class TypeRecord {
    public final TypeElement element;
    public final DeclaredType type;

    TypeRecord(final TypeElement element, final DeclaredType type) {
      this.element = element;
      this.type = type;
    }

    @Override
    public String toString() {
      return String.format("[%s => %s]", element, type);
    }
  }
}
