package org.checkerframework.common.accumulation;

import com.github.javaparser.ParseProblemException;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.expr.BinaryExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.UnaryExpr;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.StringJoiner;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.util.Elements;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.common.accumulation.AccumulationChecker.AliasAnalysis;
import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.common.returnsreceiver.ReturnsReceiverAnnotatedTypeFactory;
import org.checkerframework.common.returnsreceiver.ReturnsReceiverChecker;
import org.checkerframework.common.returnsreceiver.qual.This;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType;
import org.checkerframework.framework.type.ElementQualifierHierarchy;
import org.checkerframework.framework.type.QualifierHierarchy;
import org.checkerframework.framework.type.treeannotator.ListTreeAnnotator;
import org.checkerframework.framework.type.treeannotator.TreeAnnotator;
import org.checkerframework.javacutil.AnnotationBuilder;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.BugInCF;
import org.checkerframework.javacutil.TreeUtils;
import org.checkerframework.javacutil.TypeSystemError;
import org.checkerframework.javacutil.UserError;
import org.plumelib.util.CollectionsPlume;

/**
 * An annotated type factory for an accumulation checker.
 *
 * <p>New accumulation checkers should extend this class and implement a constructor, which should
 * take a {@link BaseTypeChecker} and call both the constructor defined in this class and {@link
 * #postInit()}.
 */
public abstract class AccumulationAnnotatedTypeFactory extends BaseAnnotatedTypeFactory {

  /** The typechecker associated with this factory. */
  public final AccumulationChecker accumulationChecker;

  /**
   * The canonical top annotation for this accumulation checker: an instance of the accumulator
   * annotation with no arguments.
   */
  public final AnnotationMirror top;

  /** The canonical bottom annotation for this accumulation checker. */
  public final AnnotationMirror bottom;

  /**
   * The annotation that accumulates things in this accumulation checker. Must be an annotation with
   * exactly one field named "value" whose type is a String array.
   */
  private final Class<? extends Annotation> accumulator;

  /**
   * The predicate annotation for this accumulation analysis, or null if predicates are not
   * supported. A predicate annotation must have a single element named "value" of type String.
   */
  private final @MonotonicNonNull Class<? extends Annotation> predicate;

  /**
   * Create an annotated type factory for an accumulation checker.
   *
   * @param checker the checker
   * @param accumulator the accumulator type in the hierarchy. Must be an annotation with a single
   *     argument named "value" whose type is a String array.
   * @param bottom the bottom type in the hierarchy, which must be a subtype of {@code accumulator}.
   *     The bottom type should be an annotation with no arguments.
   * @param predicate the predicate annotation. Either null (if predicates are not supported), or an
   *     annotation with a single element named "value" whose type is a String.
   */
  protected AccumulationAnnotatedTypeFactory(
      BaseTypeChecker checker,
      Class<? extends Annotation> accumulator,
      Class<? extends Annotation> bottom,
      @Nullable Class<? extends Annotation> predicate) {
    super(checker);
    if (!(checker instanceof AccumulationChecker)) {
      throw new TypeSystemError(
          "AccumulationAnnotatedTypeFactory cannot be used with a checker "
              + "class that is not a subtype of AccumulationChecker. Found class: "
              + checker.getClass());
    }
    this.accumulationChecker = (AccumulationChecker) checker;

    this.accumulator = accumulator;
    // Check that the requirements of the accumulator are met.
    Method[] accDeclaredMethods = accumulator.getDeclaredMethods();
    if (accDeclaredMethods.length != 1) {
      rejectMalformedAccumulator("have exactly one element");
    }

    Method accValue = accDeclaredMethods[0];
    if (accValue.getName() != "value") { // interned
      rejectMalformedAccumulator("name its element \"value\"");
    }
    if (!accValue.getReturnType().isInstance(new String[0])) {
      rejectMalformedAccumulator("have an element of type String[]");
    }
    if (accValue.getDefaultValue() == null || ((String[]) accValue.getDefaultValue()).length != 0) {
      rejectMalformedAccumulator("have the empty String array {} as its default value");
    }

    this.predicate = predicate;
    // If there is a predicate annotation, check that its requirements are met.
    if (predicate != null) {
      Method[] predDeclaredMethods = predicate.getDeclaredMethods();
      if (predDeclaredMethods.length != 1) {
        rejectMalformedPredicate("have exactly one element");
      }
      Method predValue = predDeclaredMethods[0];
      if (predValue.getName() != "value") { // interned
        rejectMalformedPredicate("name its element \"value\"");
      }
      if (!predValue.getReturnType().isInstance("")) {
        rejectMalformedPredicate("have an element of type String");
      }
    }

    this.bottom = AnnotationBuilder.fromClass(elements, bottom);
    this.top = createAccumulatorAnnotation(Collections.emptyList());

    // Every subclass must call postInit!  This does not do so.
  }

  /**
   * Create an annotated type factory for an accumulation checker.
   *
   * @param checker the checker
   * @param accumulator the accumulator type in the hierarchy. Must be an annotation with a single
   *     argument named "value" whose type is a String array.
   * @param bottom the bottom type in the hierarchy, which must be a subtype of {@code accumulator}.
   *     The bottom type should be an annotation with no arguments.
   */
  protected AccumulationAnnotatedTypeFactory(
      BaseTypeChecker checker,
      Class<? extends Annotation> accumulator,
      Class<? extends Annotation> bottom) {
    this(checker, accumulator, bottom, null);
  }

  /**
   * Common error message for malformed accumulator annotation.
   *
   * @param missing what is missing from the accumulator, suitable for use in this string to replace
   *     $MISSING$: "The accumulator annotation Foo must $MISSING$."
   */
  private void rejectMalformedAccumulator(String missing) {
    rejectMalformedAnno("accumulator", accumulator, missing);
  }

  /**
   * Common error message for malformed predicate annotation.
   *
   * @param missing what is missing from the predicate, suitable for use in this string to replace
   *     $MISSING$: "The predicate annotation Foo must $MISSING$."
   */
  private void rejectMalformedPredicate(String missing) {
    rejectMalformedAnno("predicate", predicate, missing);
  }

  /**
   * Common error message implementation. Call rejectMalformedAccumulator or
   * rejectMalformedPredicate as appropriate, rather than this method directly.
   *
   * @param annoTypeName the display name for the type of malformed annotation, such as
   *     "accumulator"
   * @param anno the malformed annotation
   * @param missing what is missing from the annotation, suitable for use in this string to replace
   *     $MISSING$: "The accumulator annotation Foo must $MISSING$."
   */
  private void rejectMalformedAnno(
      String annoTypeName, Class<? extends Annotation> anno, String missing) {
    throw new BugInCF("The " + annoTypeName + " annotation " + anno + " must " + missing + ".");
  }

  /**
   * Creates a new instance of the accumulator annotation that contains the elements of {@code
   * values}.
   *
   * @param values the arguments to the annotation. The values can contain duplicates and can be in
   *     any order.
   * @return an annotation mirror representing the accumulator annotation with {@code values}'s
   *     arguments; this is top if {@code values} is empty
   */
  public AnnotationMirror createAccumulatorAnnotation(List<String> values) {
    AnnotationBuilder builder = new AnnotationBuilder(processingEnv, accumulator);
    builder.setValue("value", CollectionsPlume.withoutDuplicates(values));
    return builder.build();
  }

  /**
   * Creates a new instance of the accumulator annotation that contains exactly one value.
   *
   * @param value the argument to the annotation
   * @return an annotation mirror representing the accumulator annotation with {@code value} as its
   *     argument
   */
  public AnnotationMirror createAccumulatorAnnotation(String value) {
    AnnotationBuilder builder = new AnnotationBuilder(processingEnv, accumulator);
    builder.setValue("value", Collections.singletonList(value));
    return builder.build();
  }

  /**
   * Returns true if the return type of the given method invocation tree has an @This annotation
   * from the Returns Receiver Checker.
   *
   * @param tree a method invocation tree
   * @return true if the method being invoked returns its receiver
   */
  public boolean returnsThis(final MethodInvocationTree tree) {
    if (!accumulationChecker.isEnabled(AliasAnalysis.RETURNS_RECEIVER)) {
      return false;
    }
    // Must call `getTypeFactoryOfSubchecker` each time, not store and reuse.
    ReturnsReceiverAnnotatedTypeFactory rrATF =
        getTypeFactoryOfSubchecker(ReturnsReceiverChecker.class);
    ExecutableElement methodEle = TreeUtils.elementFromUse(tree);
    AnnotatedExecutableType methodAtm = rrATF.getAnnotatedType(methodEle);
    AnnotatedTypeMirror rrType = methodAtm.getReturnType();
    return rrType != null && rrType.hasAnnotation(This.class);
  }

  /**
   * Is the given annotation an accumulator annotation? Returns false if the argument is {@link
   * #bottom}.
   *
   * @param anm an annotation mirror
   * @return true if the annotation mirror is an instance of this factory's accumulator annotation
   */
  public boolean isAccumulatorAnnotation(AnnotationMirror anm) {
    return areSameByClass(anm, accumulator);
  }

  @Override
  protected TreeAnnotator createTreeAnnotator() {
    return new ListTreeAnnotator(super.createTreeAnnotator(), new AccumulationTreeAnnotator(this));
  }

  /**
   * This tree annotator implements the following rule(s):
   *
   * <dl>
   *   <dt>RRA
   *   <dd>If a method returns its receiver, and the receiver has an accumulation type, then the
   *       default type of the method's return value is the type of the receiver.
   * </dl>
   */
  protected class AccumulationTreeAnnotator extends TreeAnnotator {

    /**
     * Creates an instance of this tree annotator for the given type factory.
     *
     * @param factory the type factory
     */
    public AccumulationTreeAnnotator(AccumulationAnnotatedTypeFactory factory) {
      super(factory);
    }

    /**
     * Implements rule RRA.
     *
     * <p>This implementation propagates types from the receiver to the return value, without
     * change. Subclasses may override this method to also add additional properties, as
     * appropriate.
     *
     * @param tree a method invocation tree
     * @param type the type of {@code tree} (i.e. the return type of the invoked method). Is
     *     (possibly) side-effected by this method.
     * @return nothing, works by side-effect on {@code type}
     */
    @Override
    public Void visitMethodInvocation(MethodInvocationTree tree, AnnotatedTypeMirror type) {
      if (returnsThis(tree)) {
        // There is a @This annotation on the return type of the invoked method.
        ExpressionTree receiverTree = TreeUtils.getReceiverTree(tree.getMethodSelect());
        AnnotatedTypeMirror receiverType =
            receiverTree == null ? null : getAnnotatedType(receiverTree);
        // The current type of the receiver, or top if none exists.
        AnnotationMirror receiverAnno =
            receiverType == null ? top : receiverType.getAnnotationInHierarchy(top);

        AnnotationMirror returnAnno = type.getAnnotationInHierarchy(top);
        type.replaceAnnotation(qualHierarchy.greatestLowerBound(returnAnno, receiverAnno));
      }
      return super.visitMethodInvocation(tree, type);
    }
  }

  @Override
  protected QualifierHierarchy createQualifierHierarchy() {
    return new AccumulationQualifierHierarchy(this.getSupportedTypeQualifiers(), this.elements);
  }

  /**
   * Returns all the values that anno has accumulated.
   *
   * @param anno an accumulator annotation; must not be bottom
   * @return the list of values the annotation has accumulated; it is a new list, so it is safe for
   *     clients to side-effect
   */
  public List<String> getAccumulatedValues(AnnotationMirror anno) {
    if (!isAccumulatorAnnotation(anno)) {
      throw new BugInCF(anno + " isn't an accumulator annotation");
    }
    List<String> values =
        AnnotationUtils.getElementValueArrayOrNull(anno, "value", String.class, false);
    if (values == null) {
      return Collections.emptyList();
    } else {
      return values;
    }
  }

  /**
   * All accumulation analyses share a similar type hierarchy. This class implements the subtyping,
   * LUB, and GLB for that hierarchy. The lattice looks like:
   *
   * <pre>
   *       acc()
   *      /   \
   * acc(x)   acc(y) ...
   *      \   /
   *     acc(x,y) ...
   *        |
   *      bottom
   * </pre>
   *
   * Predicate subtyping is defined as follows:
   *
   * <ul>
   *   <li>An accumulator is a subtype of a predicate if substitution from the accumulator to the
   *       predicate makes the predicate true. For example, {@code Acc(A)} is a subtype of {@code
   *       AccPred("A || B")}, because when A is replaced with {@code true} and B is replaced with
   *       {@code false}, the resulting boolean formula evaluates to true.
   *   <li>A predicate P is a subtype of an accumulator iff after converting the accumulator into a
   *       predicate representing the conjunction of its elements, P is a subtype of that predicate
   *       according to the rule for subtyping between two predicates defined below.
   *   <li>A predicate P is a subtype of another predicate Q iff P and Q are equal. An extension
   *       point ({@link #isPredicateSubtype(String, String)}) is provided to allow more complex
   *       subtyping behavior between predicates. (The "correct" subtyping rule is that P is a
   *       subtype of Q iff P implies Q. That rule would require an SMT solver in the general case,
   *       which is undesirable because it would require an external dependency. A user can override
   *       {@link #isPredicateSubtype(String, String)} if they require more precise subtyping; the
   *       check described here is overly conservative (and therefore sound), but not very precise.)
   * </ul>
   */
  protected class AccumulationQualifierHierarchy extends ElementQualifierHierarchy {

    /**
     * Creates a ElementQualifierHierarchy from the given classes.
     *
     * @param qualifierClasses classes of annotations that are the qualifiers for this hierarchy
     * @param elements element utils
     */
    protected AccumulationQualifierHierarchy(
        Collection<Class<? extends Annotation>> qualifierClasses, Elements elements) {
      super(qualifierClasses, elements);
    }

    /**
     * GLB in this type system is set union of the arguments of the two annotations, unless one of
     * them is bottom, in which case the result is also bottom.
     */
    @Override
    public AnnotationMirror greatestLowerBound(
        final AnnotationMirror a1, final AnnotationMirror a2) {
      if (AnnotationUtils.areSame(a1, bottom) || AnnotationUtils.areSame(a2, bottom)) {
        return bottom;
      }

      if (isPolymorphicQualifier(a1) && isPolymorphicQualifier(a2)) {
        return a1;
      } else if (isPolymorphicQualifier(a1) || isPolymorphicQualifier(a2)) {
        return bottom;
      }

      // If either is a predicate, then both should be converted to predicates and and-ed.
      if (isPredicate(a1) || isPredicate(a2)) {
        String a1Pred = convertToPredicate(a1);
        String a2Pred = convertToPredicate(a2);
        // check for top
        if (a1Pred.isEmpty()) {
          return a2;
        } else if (a2Pred.isEmpty()) {
          return a1;
        } else {
          return createPredicateAnnotation("(" + a1Pred + ") && (" + a2Pred + ")");
        }
      }

      List<String> a1Val = getAccumulatedValues(a1);
      List<String> a2Val = getAccumulatedValues(a2);
      // Avoid creating new annotation objects in the common case.
      if (a1Val.containsAll(a2Val)) {
        return a1;
      }
      if (a2Val.containsAll(a1Val)) {
        return a2;
      }
      a1Val.addAll(a2Val); // union
      return createAccumulatorAnnotation(a1Val);
    }

    /**
     * LUB in this type system is set intersection of the arguments of the two annotations, unless
     * one of them is bottom, in which case the result is the other annotation.
     */
    @Override
    public AnnotationMirror leastUpperBound(final AnnotationMirror a1, final AnnotationMirror a2) {
      if (AnnotationUtils.areSame(a1, bottom)) {
        return a2;
      } else if (AnnotationUtils.areSame(a2, bottom)) {
        return a1;
      }

      if (isPolymorphicQualifier(a1) && isPolymorphicQualifier(a2)) {
        return a1;
      } else if (isPolymorphicQualifier(a1) || isPolymorphicQualifier(a2)) {
        return top;
      }

      // If either is a predicate, then both should be converted to predicates and or-ed.
      if (isPredicate(a1) || isPredicate(a2)) {
        String a1Pred = convertToPredicate(a1);
        String a2Pred = convertToPredicate(a2);
        // check for top
        if (a1Pred.isEmpty()) {
          return a1;
        } else if (a2Pred.isEmpty()) {
          return a2;
        } else {
          return createPredicateAnnotation("(" + a1Pred + ") || (" + a2Pred + ")");
        }
      }

      List<String> a1Val = getAccumulatedValues(a1);
      List<String> a2Val = getAccumulatedValues(a2);
      // Avoid creating new annotation objects in the common case.
      if (a1Val.containsAll(a2Val)) {
        return a2;
      }
      if (a2Val.containsAll(a1Val)) {
        return a1;
      }
      a1Val.retainAll(a2Val); // intersection
      return createAccumulatorAnnotation(a1Val);
    }

    /** isSubtype in this type system is subset. */
    @Override
    public boolean isSubtype(final AnnotationMirror subAnno, final AnnotationMirror superAnno) {
      if (AnnotationUtils.areSame(subAnno, bottom)) {
        return true;
      } else if (AnnotationUtils.areSame(superAnno, bottom)) {
        return false;
      }

      if (isPolymorphicQualifier(subAnno)) {
        if (isPolymorphicQualifier(superAnno)) {
          return true;
        } else {
          // Use this slightly more expensive conversion here because this is a rare code path and
          // it's simpler to read than checking for both predicate and non-predicate forms of top.
          return "".equals(convertToPredicate(superAnno));
        }
      } else if (isPolymorphicQualifier(superAnno)) {
        // Polymorphic annotations are only a supertype of other polymorphic annotations and
        // the bottom type, both of which have already been checked above.
        return false;
      }

      if (isPredicate(subAnno)) {
        return isPredicateSubtype(convertToPredicate(subAnno), convertToPredicate(superAnno));
      } else if (isPredicate(superAnno)) {
        return evaluatePredicate(subAnno, convertToPredicate(superAnno));
      }

      List<String> subVal = getAccumulatedValues(subAnno);
      List<String> superVal = getAccumulatedValues(superAnno);
      return subVal.containsAll(superVal);
    }
  }

  /**
   * Extension point for subtyping behavior between predicates. This implementation conservatively
   * returns true only if the predicates are equal, or if the prospective supertype (q) is
   * equivalent to top (that is, the empty string).
   *
   * @param p a predicate
   * @param q another predicate
   * @return true if p is a subtype of q
   */
  protected boolean isPredicateSubtype(String p, String q) {
    return "".equals(q) || p.equals(q);
  }

  /**
   * Evaluates whether the accumulator annotation {@code subAnno} makes the predicate {@code pred}
   * true.
   *
   * @param subAnno an accumulator annotation
   * @param pred a predicate
   * @return whether the accumulator annotation satisfies the predicate
   */
  protected boolean evaluatePredicate(AnnotationMirror subAnno, String pred) {
    if (!isAccumulatorAnnotation(subAnno)) {
      throw new BugInCF(
          "tried to evaluate a predicate using an annotation that wasn't an accumulator: "
              + subAnno);
    }
    List<String> trueVariables = getAccumulatedValues(subAnno);
    return evaluatePredicate(trueVariables, pred);
  }

  /**
   * Checks that the given annotation either:
   *
   * <ul>
   *   <li>does not contain a predicate, or
   *   <li>contains a parse-able predicate
   * </ul>
   *
   * Used by the visitor to throw "predicate" errors; thus must be package-private.
   *
   * @param anm any annotation supported by this checker
   * @return null if there is nothing wrong with the annotation, or an error message indicating the
   *     problem if it has an invalid predicate
   */
  /* package-private */
  @Nullable String isValidPredicate(AnnotationMirror anm) {
    String pred = convertToPredicate(anm);
    try {
      evaluatePredicate(Collections.emptyList(), pred);
    } catch (UserError ue) {
      return ue.getLocalizedMessage();
    }
    return null;
  }

  /**
   * Evaluates whether treating the variables in {@code trueVariables} as {@code true} literals (and
   * all other names as {@code false} literals) makes the predicate {@code pred} evaluate to true.
   *
   * @param trueVariables a list of names that should be replaced with {@code true}
   * @param pred a predicate
   * @return whether the true variables satisfy the predicate
   */
  protected boolean evaluatePredicate(List<String> trueVariables, String pred) {
    Expression expression;
    try {
      expression = StaticJavaParser.parseExpression(pred);
    } catch (ParseProblemException p) {
      throw new UserError("unparsable predicate: " + pred + ". Parse exception: " + p);
    }
    return evaluateBooleanExpression(expression, trueVariables);
  }

  /**
   * Evaluates a boolean expression, in JavaParser format, that contains only and, or, parentheses,
   * logical complement, and boolean literal nodes.
   *
   * @param expression a JavaParser boolean expression
   * @param trueVariables the names of the variables that should be considered "true"; all other
   *     literals are considered "false"
   * @return the result of evaluating the expression
   */
  private boolean evaluateBooleanExpression(Expression expression, List<String> trueVariables) {
    if (expression.isNameExpr()) {
      return trueVariables.contains(expression.asNameExpr().getNameAsString());
    } else if (expression.isBinaryExpr()) {
      if (expression.asBinaryExpr().getOperator() == BinaryExpr.Operator.OR) {
        return evaluateBooleanExpression(expression.asBinaryExpr().getLeft(), trueVariables)
            || evaluateBooleanExpression(expression.asBinaryExpr().getRight(), trueVariables);
      } else if (expression.asBinaryExpr().getOperator() == BinaryExpr.Operator.AND) {
        return evaluateBooleanExpression(expression.asBinaryExpr().getLeft(), trueVariables)
            && evaluateBooleanExpression(expression.asBinaryExpr().getRight(), trueVariables);
      }
    } else if (expression.isEnclosedExpr()) {
      return evaluateBooleanExpression(expression.asEnclosedExpr().getInner(), trueVariables);
    } else if (expression.isUnaryExpr()) {
      if (expression.asUnaryExpr().getOperator() == UnaryExpr.Operator.LOGICAL_COMPLEMENT) {
        return !evaluateBooleanExpression(expression.asUnaryExpr().getExpression(), trueVariables);
      }
    }
    // This could be a BugInCF if there is a bug in the code above.
    throw new UserError(
        "encountered an unexpected type of expression in a "
            + "predicate expression: "
            + expression
            + " was of type "
            + expression.getClass());
  }

  /**
   * Creates a new predicate annotation from the given string.
   *
   * @param p a valid predicate
   * @return an annotation representing that predicate
   */
  protected AnnotationMirror createPredicateAnnotation(String p) {
    AnnotationBuilder builder = new AnnotationBuilder(processingEnv, predicate);
    builder.setValue("value", p);
    return builder.build();
  }

  /**
   * Converts the given annotation mirror to a predicate.
   *
   * @param anno an annotation
   * @return the predicate, as a String, that is equivalent to that annotation. May return the empty
   *     string.
   */
  protected String convertToPredicate(AnnotationMirror anno) {
    if (AnnotationUtils.areSame(anno, bottom)) {
      return "false";
    } else if (isPredicate(anno)) {
      String result = AnnotationUtils.getElementValueOrNull(anno, "value", String.class, false);
      return result == null ? "" : result;
    } else if (isAccumulatorAnnotation(anno)) {
      List<String> values = getAccumulatedValues(anno);
      StringJoiner sj = new StringJoiner(" && ");
      for (String value : values) {
        sj.add(value);
      }
      return sj.toString();
    } else {
      throw new BugInCF("annotation is not bottom, a predicate, or an accumulator: " + anno);
    }
  }

  /**
   * Returns true if anno is a predicate annotation.
   *
   * @param anno an annotation
   * @return true if anno is a predicate annotation
   */
  protected boolean isPredicate(AnnotationMirror anno) {
    return predicate != null && areSameByClass(anno, predicate);
  }
}
