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

import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.lang.model.type.TypeVariable;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.util.typeinference.TypeArgInferenceUtil;

/**
 * AFConstraint represent the initial constraints used to infer type arguments for method
 * invocations and new class invocations. These constraints are simplified then converted to
 * TUConstraints during type argument inference.
 *
 * <p>Subclasses of AFConstraint represent the following <a
 * href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.7">types of
 * constraints</a>:
 *
 * <p>A 《 F and F 》 A both imply that A is convertible to F. F 《 A and A 》 F both imply that F is
 * convertible to A (this may happen due to wildcard/typevar bounds and recursive types) A = F
 * implies that A is exactly F
 *
 * <p>In the Checker Framework a type, A will be convertible to another type F, if
 * AnnotatedTypes.asSuper will return a non-null value when A is passed as a subtype and F the
 * supertype to the method.
 *
 * <p>In Java type A will be convertible to another type F if there exists a conversion
 * context/method that transforms the one type into the other.
 *
 * <p>A 《 F and F 》 A are represented by class A2F F 《 A and A 》 F are represented by class F2A F =
 * A is represented by class FIsA
 */
public abstract class AFConstraint {
  /** The argument type. */
  public final AnnotatedTypeMirror argument;
  /** The formal parameter type. */
  public final AnnotatedTypeMirror formalParameter;

  /** Create a constraint for type arguments for a methodd invocation or new class invocation. */
  protected AFConstraint(
      final AnnotatedTypeMirror argument, final AnnotatedTypeMirror formalParameter) {
    this.argument = argument;
    this.formalParameter = formalParameter;
    TypeArgInferenceUtil.checkForUninferredTypes(argument);
  }

  /**
   * Returns true if this constraint can't be broken up into other constraints or further
   * simplified. In general, if either argument or formal parameter is a use of the type parameters
   * we are inferring over then the constraint cannot be reduced further.
   *
   * @param targets the type parameters whose arguments we are trying to solve for
   * @return true if this constraint can't be broken up into other constraints or further simplified
   */
  public boolean isIrreducible(final Set<TypeVariable> targets) {
    return TypeArgInferenceUtil.isATarget(argument, targets)
        || TypeArgInferenceUtil.isATarget(formalParameter, targets);
  }

  @Override
  public boolean equals(@Nullable Object thatObject) {
    if (this == thatObject) {
      return true;
    } // else

    if (thatObject == null || this.getClass() != thatObject.getClass()) {
      return false;
    }

    final AFConstraint that = (AFConstraint) thatObject;

    return this.argument.equals(that.argument) && this.formalParameter.equals(that.formalParameter);
  }

  @Override
  public int hashCode() {
    return Objects.hash(this.getClass(), formalParameter, argument);
  }

  /**
   * Once AFConstraints are irreducible it can be converted to a TU constraint, constraints between
   * individual type parameters for which we are inferring an argument (T) and Java types (U).
   *
   * @return a TUConstraint that represents this AFConstraint
   */
  public abstract TUConstraint toTUConstraint();

  /**
   * Given a partial solution to our type argument inference, replace any uses of type parameters
   * that have been solved with their arguments.
   *
   * <p>That is: Let S be a partial solution to our inference (i.e. we have inferred type arguments
   * for some types) Let S be a map {@code (T0 => A0, T1 => A1, ..., TN => AN)} where Ti is a type
   * parameter and Ai is its solved argument. For all uses of Ti in this constraint, replace them
   * with Ai.
   *
   * <p>For the mapping {@code (T0 => A0)}, the following constraint: {@code ArrayList<T0> <<
   * List<T1>}
   *
   * <p>Becomes: {@code ArrayList<A0> << List<T1>}
   *
   * <p>A constraint: {@code T0 << T1}
   *
   * <p>Becomes: {@code A0 << T1}
   *
   * @param substitutions a mapping of target type parameter to the type argument to
   * @return a new constraint that contains no use of the keys in substitutions
   */
  public AFConstraint substitute(final Map<TypeVariable, AnnotatedTypeMirror> substitutions) {
    final AnnotatedTypeMirror newArgument =
        TypeArgInferenceUtil.substitute(substitutions, argument);
    final AnnotatedTypeMirror newFormalParameter =
        TypeArgInferenceUtil.substitute(substitutions, formalParameter);
    return construct(newArgument, newFormalParameter);
  }

  /** Used to create a new constraint of the same subclass of AFConstraint. */
  protected abstract AFConstraint construct(
      AnnotatedTypeMirror newArgument, AnnotatedTypeMirror newFormalParameter);
}
