package org.checkerframework.framework.util.typeinference.solver;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
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.AnnotationMirror;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.Types;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable;
import org.checkerframework.framework.type.QualifierHierarchy;
import org.checkerframework.framework.util.AnnotatedTypes;
import org.checkerframework.framework.util.AnnotationMirrorMap;
import org.checkerframework.framework.util.AnnotationMirrorSet;
import org.checkerframework.framework.util.typeinference.TypeArgInferenceUtil;
import org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType;
import org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Equalities;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.BugInCF;

/**
 * Infers type arguments by using the Least Upper Bound computation on the supertype relationships
 * in a constraint map.
 */
public class SupertypesSolver {

  /**
   * Infers type arguments using supertype constraints.
   *
   * @param remainingTargets targets for which we still need to infer a value
   * @param constraintMap the set of constraints for all targets
   * @return a mapping from target to inferred type. Note this class always infers concrete types
   *     and will not infer that the target is equivalent to another target.
   */
  public InferenceResult solveFromSupertypes(
      final Set<TypeVariable> remainingTargets,
      final ConstraintMap constraintMap,
      final AnnotatedTypeFactory typeFactory) {
    // infer a type for all targets that have supertype constraints
    final Lubs lubs = targetToTypeLubs(remainingTargets, constraintMap, typeFactory);

    // add the lub types to the outgoing solution
    final InferenceResult solution = new InferenceResult();
    for (final TypeVariable target : remainingTargets) {
      final AnnotatedTypeMirror lub = lubs.getType(target);
      AnnotationMirrorMap<AnnotationMirror> lubAnnos = lubs.getPrimaries(target);

      // we may have a partial solution present in the equality constraints, override
      // any annotations found in the lub with annotations from the equality constraints
      final InferredValue inferred;
      if (lub != null) {
        inferred = mergeLubTypeWithEqualities(target, lub, constraintMap, typeFactory);
      } else if (lubAnnos != null) {
        inferred = mergeLubAnnosWithEqualities(target, lubAnnos, constraintMap, typeFactory);
      } else {
        inferred = null;
      }

      if (inferred != null) {
        solution.put(target, inferred);
      }
    }

    return solution;
  }

  /**
   * We previously found a type that is equal to target but not in all hierarchies. Use the primary
   * annotations from the lub type to fill in the missing annotations in this type. Use that type as
   * the inferred argument.
   *
   * <p>If we failed to infer any annotation for a given hierarchy, either previously from
   * equalities or from the lub, return null.
   */
  protected InferredType mergeLubTypeWithEqualities(
      final TypeVariable target,
      final AnnotatedTypeMirror lub,
      final ConstraintMap constraintMap,
      final AnnotatedTypeFactory typeFactory) {
    final Equalities equalities = constraintMap.getConstraints(target).equalities;
    final AnnotationMirrorSet tops =
        new AnnotationMirrorSet(typeFactory.getQualifierHierarchy().getTopAnnotations());

    if (!equalities.types.isEmpty()) {
      // there should be only one equality type if any at this point
      final Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet> eqEntry =
          equalities.types.entrySet().iterator().next();
      final AnnotatedTypeMirror equalityType = eqEntry.getKey();
      final AnnotationMirrorSet equalityAnnos = eqEntry.getValue();

      boolean failed = false;
      for (final AnnotationMirror top : tops) {
        if (!equalityAnnos.contains(top)) {
          final AnnotationMirror lubAnno = lub.getAnnotationInHierarchy(top);
          if (lubAnno == null) {
            // If the LUB and the Equality were the SAME typevar, and the lub was
            // unannotated then "NO ANNOTATION" is the correct choice.
            if (lub.getKind() == TypeKind.TYPEVAR
                && typeFactory.types.isSameType(
                    equalityType.getUnderlyingType(), lub.getUnderlyingType())) {
              equalityAnnos.add(top);
            } else {
              failed = true;
            }

          } else {
            equalityType.replaceAnnotation(lubAnno);
            equalityAnnos.add(top);
          }
        }
      }

      if (!failed) {
        return new InferredType(equalityType);
      }
    }

    return new InferredType(lub);
  }

  /**
   * We previously found a type that is equal to target but not in all hierarchies. Use the primary
   * annotations from the lub annos to fill in the missing annotations in this type. Use that type
   * as the inferred argument.
   *
   * <p>If we failed to infer any annotation for a given hierarchy, either previously from
   * equalities or from the lub, return null.
   */
  protected InferredType mergeLubAnnosWithEqualities(
      final TypeVariable target,
      final AnnotationMirrorMap<AnnotationMirror> lubAnnos,
      final ConstraintMap constraintMap,
      final AnnotatedTypeFactory typeFactory) {
    final Equalities equalities = constraintMap.getConstraints(target).equalities;
    final AnnotationMirrorSet tops =
        new AnnotationMirrorSet(typeFactory.getQualifierHierarchy().getTopAnnotations());

    if (!equalities.types.isEmpty()) {
      // there should be only equality type if any at this point
      final Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet> eqEntry =
          equalities.types.entrySet().iterator().next();
      final AnnotatedTypeMirror equalityType = eqEntry.getKey();
      final AnnotationMirrorSet equalityAnnos = eqEntry.getValue();

      boolean failed = false;
      for (final AnnotationMirror top : tops) {
        if (!equalityAnnos.contains(top)) {
          final AnnotationMirror lubAnno = lubAnnos.get(top);
          if (lubAnno == null) {
            failed = true;

          } else {
            equalityType.replaceAnnotation(lubAnno);
            equalityAnnos.add(top);
          }
        }
      }

      if (!failed) {
        return new InferredType(equalityType);
      }
    }

    return null;
  }

  /** Holds the least upper bounds for every target type parameter. */
  static class Lubs {
    public final Map<TypeVariable, AnnotatedTypeMirror> types = new LinkedHashMap<>();
    public final Map<TypeVariable, AnnotationMirrorMap<AnnotationMirror>> primaries =
        new LinkedHashMap<>();

    public void addPrimaries(
        final TypeVariable target, AnnotationMirrorMap<AnnotationMirror> primaries) {
      this.primaries.put(target, new AnnotationMirrorMap<>(primaries));
    }

    public void addType(final TypeVariable target, final AnnotatedTypeMirror type) {
      types.put(target, type);
    }

    public AnnotationMirrorMap<AnnotationMirror> getPrimaries(final TypeVariable target) {
      return primaries.get(target);
    }

    public AnnotatedTypeMirror getType(final TypeVariable target) {
      return types.get(target);
    }
  }

  /**
   * For each target, lub all of the types/annotations in its supertypes constraints and return the
   * lubs.
   *
   * @param remainingTargets targets that do not already have an inferred type argument
   * @param constraintMap the set of constraints for all targets
   * @return the lub determined for each target that has at least 1 supertype constraint
   */
  private Lubs targetToTypeLubs(
      Set<TypeVariable> remainingTargets,
      ConstraintMap constraintMap,
      AnnotatedTypeFactory typeFactory) {
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    final AnnotationMirrorSet tops =
        new AnnotationMirrorSet(qualifierHierarchy.getTopAnnotations());

    Lubs solution = new Lubs();

    AnnotationMirrorMap<AnnotationMirror> lubOfPrimaries = new AnnotationMirrorMap<>();

    List<TypeVariable> targetsSupertypesLast = new ArrayList<>(remainingTargets);

    final Types types = typeFactory.getProcessingEnv().getTypeUtils();
    // If we have two type variables <A, A extends B> order them B then A
    // this is required because we will use the fact that A must be above B
    // when determining the LUB of A
    Collections.sort(
        targetsSupertypesLast,
        new Comparator<TypeVariable>() {
          @Override
          public int compare(TypeVariable o1, TypeVariable o2) {
            if (types.isSubtype(o1, o2)) {
              return -1;
            } else if (types.isSubtype(o2, o1)) {
              return 1;
            }

            return 0;
          }
        });

    for (final TypeVariable target : targetsSupertypesLast) {
      TargetConstraints targetRecord = constraintMap.getConstraints(target);
      final AnnotationMirrorMap<AnnotationMirrorSet> subtypeAnnos =
          targetRecord.supertypes.primaries;
      final Map<AnnotatedTypeMirror, AnnotationMirrorSet> subtypesOfTarget =
          targetRecord.supertypes.types;

      // If this target is a supertype of other targets and those targets have already been lubbed
      // add that LUB to the list of lubs for this target (as it must be above this target).
      propagatePreviousLubs(targetRecord, solution, subtypesOfTarget);

      // lub all the primary annotations and put them in lubOfPrimaries
      lubPrimaries(lubOfPrimaries, subtypeAnnos, tops, qualifierHierarchy);
      solution.addPrimaries(target, lubOfPrimaries);

      if (!subtypesOfTarget.isEmpty()) {
        final AnnotatedTypeMirror lub = leastUpperBound(target, typeFactory, subtypesOfTarget);
        final AnnotationMirrorSet effectiveLubAnnos =
            new AnnotationMirrorSet(lub.getEffectiveAnnotations());

        for (AnnotationMirror lubAnno : effectiveLubAnnos) {
          final AnnotationMirror hierarchy = qualifierHierarchy.getTopAnnotation(lubAnno);
          final AnnotationMirror primaryLub = lubOfPrimaries.get(hierarchy);

          if (primaryLub != null) {
            if (qualifierHierarchy.isSubtype(lubAnno, primaryLub)
                && !AnnotationUtils.areSame(lubAnno, primaryLub)) {
              lub.replaceAnnotation(primaryLub);
            }
          }
        }

        solution.addType(target, lub);
      }
    }
    return solution;
  }

  /**
   * If the target corresponding to targetRecord must be a supertype of another target for which we
   * have already determined a lub, add that target's lub to this list.
   */
  protected static void propagatePreviousLubs(
      final TargetConstraints targetRecord,
      Lubs solution,
      final Map<AnnotatedTypeMirror, AnnotationMirrorSet> subtypesOfTarget) {

    for (final Map.Entry<TypeVariable, AnnotationMirrorSet> supertypeTarget :
        targetRecord.supertypes.targets.entrySet()) {
      final AnnotatedTypeMirror supertargetLub = solution.getType(supertypeTarget.getKey());
      if (supertargetLub != null) {
        AnnotationMirrorSet supertargetTypeAnnos = subtypesOfTarget.get(supertargetLub);
        if (supertargetTypeAnnos != null) {
          // there is already an equivalent type in the list of subtypes, just add
          // any hierarchies that are not in its list but are in the supertarget's list
          supertargetTypeAnnos.addAll(supertypeTarget.getValue());
        } else {
          subtypesOfTarget.put(supertargetLub, supertypeTarget.getValue());
        }
      }
    }
  }

  /**
   * For each qualifier hierarchy in tops, take the lub of the annos in subtypeAnnos that correspond
   * to that hierarchy place the lub in lubOfPrimaries.
   */
  protected static void lubPrimaries(
      AnnotationMirrorMap<AnnotationMirror> lubOfPrimaries,
      AnnotationMirrorMap<AnnotationMirrorSet> subtypeAnnos,
      AnnotationMirrorSet tops,
      QualifierHierarchy qualifierHierarchy) {

    lubOfPrimaries.clear();
    for (final AnnotationMirror top : tops) {
      final AnnotationMirrorSet annosInHierarchy = subtypeAnnos.get(top);
      if (annosInHierarchy != null && !annosInHierarchy.isEmpty()) {
        lubOfPrimaries.put(top, leastUpperBound(annosInHierarchy, qualifierHierarchy));
      } else {
        // If there are no annotations for this hierarchy, add bottom.  This happens
        // when the only constraint for a type variable is a use that is annotated in
        // this hierarchy. Calls to the method below have this property.
        // <T> void method(@NonNull T t) {}
        lubOfPrimaries.put(top, qualifierHierarchy.getBottomAnnotation(top));
      }
    }
  }

  /**
   * For each type in typeToHierarchies, if that type does not have a corresponding annotation for a
   * given hierarchy replace it with the corresponding value in lowerBoundAnnos.
   */
  public static AnnotatedTypeMirror groundMissingHierarchies(
      final Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet> typeToHierarchies,
      final AnnotationMirrorMap<AnnotationMirror> lowerBoundAnnos) {
    final AnnotationMirrorSet presentHierarchies = typeToHierarchies.getValue();
    final AnnotationMirrorSet missingAnnos = new AnnotationMirrorSet();
    for (AnnotationMirror top : lowerBoundAnnos.keySet()) {
      if (!presentHierarchies.contains(top)) {
        missingAnnos.add(lowerBoundAnnos.get(top));
      }
    }

    if (!missingAnnos.isEmpty()) {
      AnnotatedTypeMirror copy = typeToHierarchies.getKey().deepCopy();
      copy.replaceAnnotations(missingAnnos);

      return copy;
    }

    return typeToHierarchies.getKey();
  }

  /**
   * Successively calls least upper bound on the elements of types. Unlike
   * AnnotatedTypes.leastUpperBound, this method will box primitives if necessary
   */
  public static AnnotatedTypeMirror leastUpperBound(
      final TypeVariable target,
      final AnnotatedTypeFactory typeFactory,
      final Map<AnnotatedTypeMirror, AnnotationMirrorSet> types) {

    QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    AnnotatedTypeVariable targetsDeclaredType =
        (AnnotatedTypeVariable) typeFactory.getAnnotatedType(target.asElement());
    final AnnotationMirrorMap<AnnotationMirror> lowerBoundAnnos =
        TypeArgInferenceUtil.createHierarchyMap(
            new AnnotationMirrorSet(targetsDeclaredType.getLowerBound().getEffectiveAnnotations()),
            qualifierHierarchy);

    final Iterator<Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet>> typesIter =
        types.entrySet().iterator();
    if (!typesIter.hasNext()) {
      throw new BugInCF("Calling LUB on empty list.");
    }

    /**
     * If a constraint implies that a type parameter Ti is a supertype of an annotated type mirror
     * Ai but only in a subset of all qualifier hierarchies then for all other qualifier hierarchies
     * replace the primary annotation on Ai with the lowest possible annotation (ensuring that it
     * won't be the LUB unless there are no other constraints, or all other constraints imply the
     * bottom annotation is the LUB). Note: Even if we choose bottom as the lub here, the assignment
     * context may raise this annotation.
     */
    final Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet> head = typesIter.next();

    AnnotatedTypeMirror lubType = groundMissingHierarchies(head, lowerBoundAnnos);
    AnnotatedTypeMirror nextType = null;
    while (typesIter.hasNext()) {
      nextType = groundMissingHierarchies(typesIter.next(), lowerBoundAnnos);

      if (lubType.getKind().isPrimitive()) {
        if (!nextType.getKind().isPrimitive()) {
          lubType = typeFactory.getBoxedType((AnnotatedPrimitiveType) lubType);
        }
      } else if (nextType.getKind().isPrimitive()) {
        if (!lubType.getKind().isPrimitive()) {
          nextType = typeFactory.getBoxedType((AnnotatedPrimitiveType) nextType);
        }
      }
      lubType = AnnotatedTypes.leastUpperBound(typeFactory, lubType, nextType);
    }

    return lubType;
  }

  /**
   * Returns the lub of all the annotations in annos.
   *
   * @param annos a set of annotations in the same annotation hierarchy
   * @param qualifierHierarchy the qualifier hierarchy that contains each annotation
   * @return the lub of all the annotations in annos
   */
  private static final AnnotationMirror leastUpperBound(
      final Iterable<? extends AnnotationMirror> annos, QualifierHierarchy qualifierHierarchy) {
    Iterator<? extends AnnotationMirror> annoIter = annos.iterator();
    AnnotationMirror lub = annoIter.next();

    while (annoIter.hasNext()) {
      lub = qualifierHierarchy.leastUpperBound(lub, annoIter.next());
    }

    return lub;
  }
}
