package org.checkerframework.checker.mustcall;

import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.ExecutableElement;
import org.checkerframework.checker.mustcall.qual.CreatesObligation;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.cfg.node.MethodInvocationNode;
import org.checkerframework.dataflow.expression.JavaExpression;
import org.checkerframework.dataflow.expression.Unknown;
import org.checkerframework.framework.type.GenericAnnotatedTypeFactory;
import org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException;
import org.checkerframework.framework.util.StringToJavaExpression;
import org.checkerframework.javacutil.AnnotationUtils;

/**
 * This interface should be implemented by all type factories that can provide the ExecutableElement
 * needed to call {@link AnnotationUtils#getElementValueArray} when {@link
 * #getCreatesObligationExpressions(MethodInvocationNode, GenericAnnotatedTypeFactory,
 * CreatesObligationElementSupplier)} is called. This interface is needed so any type factory with
 * these elements can be used to call that method, not just the MustCallAnnotatedTypeFactory (in
 * particular, the consistency checker needs to be able to call that method with both the
 * ObjectConstruction/CalledMethods type factory and the MustCall type factory).
 */
public interface CreatesObligationElementSupplier {

  /**
   * Returns the CreatesObligation.value field/element.
   *
   * @return the CreatesObligation.value field/element
   */
  ExecutableElement getCreatesObligationValueElement();

  /**
   * Returns the CreatesObligation.List.value field/element.
   *
   * @return the CreatesObligation.List.value field/element
   */
  ExecutableElement getCreatesObligationListValueElement();

  /**
   * Returns the arguments of the @CreatesObligation annotation on the invoked method, as
   * JavaExpressions. Returns the empty set if the given method has no @CreatesObligation
   * annotation.
   *
   * <p>If any expression is unparseable, this method reports an error and returns the empty set.
   *
   * @param n a method invocation
   * @param atypeFactory the type factory to report errors and parse the expression string
   * @param supplier a type factory that can supply the executable elements for CreatesObligation
   *     and CreatesObligation.List's value elements. Usually, you should just pass atypeFactory
   *     again. The arguments are different so that the given type factory's adherence to both
   *     protocols are checked by the type system.
   * @return the arguments of the method's @CreatesObligation annotation, or an empty list
   */
  static List<JavaExpression> getCreatesObligationExpressions(
      MethodInvocationNode n,
      GenericAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory,
      CreatesObligationElementSupplier supplier) {
    AnnotationMirror createsObligationList =
        atypeFactory.getDeclAnnotation(n.getTarget().getMethod(), CreatesObligation.List.class);
    List<JavaExpression> results = new ArrayList<>(1);
    if (createsObligationList != null) {
      // Handle a set of CreatesObligation annotations.
      List<AnnotationMirror> createsObligations =
          AnnotationUtils.getElementValueArray(
              createsObligationList,
              supplier.getCreatesObligationListValueElement(),
              AnnotationMirror.class);
      for (AnnotationMirror co : createsObligations) {
        JavaExpression expr = getCreatesObligationExpression(co, n, atypeFactory, supplier);
        if (expr != null && !results.contains(expr)) {
          results.add(expr);
        }
      }
    }
    AnnotationMirror createsObligation =
        atypeFactory.getDeclAnnotation(n.getTarget().getMethod(), CreatesObligation.class);
    if (createsObligation != null) {
      JavaExpression expr =
          getCreatesObligationExpression(createsObligation, n, atypeFactory, supplier);
      if (expr != null && !results.contains(expr)) {
        results.add(expr);
      }
    }
    return results;
  }

  /**
   * Parses a single CreatesObligation annotation. Clients should use {@link
   * #getCreatesObligationExpressions(MethodInvocationNode, GenericAnnotatedTypeFactory,
   * CreatesObligationElementSupplier)}, which handles the possibility of multiple such annotations,
   * instead.
   *
   * @param createsObligation a @CreatesObligation annotation
   * @param n the invocation of a reset method
   * @param atypeFactory the type factory
   * @param supplier a type factory that can supply the executable elements for CreatesObligation
   *     and CreatesObligation.List's value elements. Usually, you should just pass atypeFactory
   *     again. The arguments are different so that the given type factory's adherence to both
   *     protocols are checked by the type system.
   * @return the Java expression representing the target, or null if the target is unparseable
   */
  static @Nullable JavaExpression getCreatesObligationExpression(
      AnnotationMirror createsObligation,
      MethodInvocationNode n,
      GenericAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory,
      CreatesObligationElementSupplier supplier) {
    // Unfortunately, there is no way to avoid passing the default string "this" here. The default
    // must be hard-coded into the client, such as here. That is the price for the efficiency of not
    // having to query the annotation definition (such queries are expensive).
    String targetStrWithoutAdaptation =
        AnnotationUtils.getElementValue(
            createsObligation, supplier.getCreatesObligationValueElement(), String.class, "this");
    // TODO: find a way to also check if the target is a known tempvar, and if so return that. That
    // should improve the quality of the error messages we give.
    JavaExpression targetExpr;
    try {
      targetExpr =
          StringToJavaExpression.atMethodInvocation(
              targetStrWithoutAdaptation, n, atypeFactory.getChecker());
      if (targetExpr instanceof Unknown) {
        issueUnparseableError(n, atypeFactory, targetStrWithoutAdaptation);
        return null;
      }
    } catch (JavaExpressionParseException e) {
      issueUnparseableError(n, atypeFactory, targetStrWithoutAdaptation);
      return null;
    }
    return targetExpr;
  }

  /**
   * Issues a createsobligation.target.unparseable error.
   *
   * @param n the node
   * @param atypeFactory the type factory to use to issue the error
   * @param unparseable the unparseable string
   */
  static void issueUnparseableError(
      MethodInvocationNode n,
      GenericAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory,
      String unparseable) {
    atypeFactory
        .getChecker()
        .reportError(
            n.getTree(),
            "createsobligation.target.unparseable",
            n.getTarget().getMethod().getSimpleName(),
            unparseable);
  }
}
