package org.checkerframework.framework.util.element;

import com.sun.source.tree.LambdaExpressionTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Attribute.TypeCompound;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.TargetType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.VariableElement;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.ElementAnnotationApplier;
import org.checkerframework.framework.util.element.ElementAnnotationUtil.UnexpectedAnnotationLocationException;
import org.checkerframework.javacutil.BugInCF;
import org.checkerframework.javacutil.Pair;

/** Adds annotations to one formal parameter of a method or lambda within a method. */
public class ParamApplier extends IndexedElementAnnotationApplier {

  /** Apply annotations from {@code element} to {@code type}. */
  public static void apply(
      AnnotatedTypeMirror type, Element element, AnnotatedTypeFactory typeFactory)
      throws UnexpectedAnnotationLocationException {
    new ParamApplier(type, element, typeFactory).extractAndApply();
  }

  public static final int RECEIVER_PARAM_INDEX = Integer.MIN_VALUE;

  public static boolean accepts(final AnnotatedTypeMirror type, final Element element) {
    return element.getKind() == ElementKind.PARAMETER;
  }

  private final Symbol.MethodSymbol enclosingMethod;
  private final boolean isLambdaParam;
  private final Integer lambdaParamIndex;
  private final LambdaExpressionTree lambdaTree;

  ParamApplier(AnnotatedTypeMirror type, Element element, AnnotatedTypeFactory typeFactory) {
    super(type, element);
    enclosingMethod = getParentMethod(element);

    if (enclosingMethod.getKind() != ElementKind.INSTANCE_INIT
        && enclosingMethod.getKind() != ElementKind.STATIC_INIT
        && enclosingMethod.getParameters().contains(element)) {
      lambdaTree = null;
      isLambdaParam = false;
      lambdaParamIndex = null;

    } else {
      Pair<VariableTree, LambdaExpressionTree> paramToEnclosingLambda =
          ElementAnnotationApplier.getParamAndLambdaTree((VariableElement) element, typeFactory);

      if (paramToEnclosingLambda != null) {
        VariableTree paramDecl = paramToEnclosingLambda.first;
        lambdaTree = paramToEnclosingLambda.second;
        isLambdaParam = true;
        lambdaParamIndex = lambdaTree.getParameters().indexOf(paramDecl);

      } else {
        lambdaTree = null;
        isLambdaParam = false;
        lambdaParamIndex = null;
      }
    }
  }

  /**
   * Returns the index of element its parent method's parameter list. Integer.MIN_VALUE if the
   * element is the receiver parameter.
   *
   * @return the index of element its parent method's parameter list. Integer.MIN_VALUE if the
   *     element is the receiver parameter
   */
  @Override
  public int getElementIndex() {
    if (isLambdaParam) {
      return lambdaParamIndex;
    }

    if (isReceiver(element)) {
      return RECEIVER_PARAM_INDEX;
    }

    final int paramIndex = enclosingMethod.getParameters().indexOf(element);
    if (paramIndex == -1) {
      throw new BugInCF(
          "Could not find parameter Element in parameter list. "
              + "Parameter( "
              + element
              + " ) Parent ( "
              + enclosingMethod
              + " ) ");
    }

    return paramIndex;
  }

  /**
   * Returns the parameter index of anno's TypeAnnotationPosition.
   *
   * @return the parameter index of anno's TypeAnnotationPosition
   */
  @Override
  public int getTypeCompoundIndex(Attribute.TypeCompound anno) {
    return anno.getPosition().parameter_index;
  }

  /**
   * Returns {TargetType.METHOD_FORMAL_PARAMETER, TargetType.METHOD_RECEIVER}.
   *
   * @return {TargetType.METHOD_FORMAL_PARAMETER, TargetType.METHOD_RECEIVER}
   */
  @Override
  protected TargetType[] annotatedTargets() {
    return new TargetType[] {TargetType.METHOD_FORMAL_PARAMETER, TargetType.METHOD_RECEIVER};
  }

  /**
   * Returns any annotation TargetType that can be found on a method.
   *
   * @return any annotation TargetType that can be found on a method
   */
  @Override
  protected TargetType[] validTargets() {
    return new TargetType[] {
      TargetType.METHOD_FORMAL_PARAMETER,
      TargetType.METHOD_RETURN,
      TargetType.THROWS,
      TargetType.METHOD_TYPE_PARAMETER,
      TargetType.METHOD_TYPE_PARAMETER_BOUND,
      TargetType.LOCAL_VARIABLE,
      TargetType.RESOURCE_VARIABLE,
      TargetType.EXCEPTION_PARAMETER,
      TargetType.NEW,
      TargetType.CAST,
      TargetType.INSTANCEOF,
      TargetType.METHOD_INVOCATION_TYPE_ARGUMENT,
      TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT,
      TargetType.METHOD_REFERENCE,
      TargetType.CONSTRUCTOR_REFERENCE,
      TargetType.METHOD_REFERENCE_TYPE_ARGUMENT,
      TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
      // TODO: from generic anonymous classes; remove when
      // we can depend on only seeing classfiles that were
      // generated by a javac that contains a fix for:
      // https://bugs.openjdk.java.net/browse/JDK-8198945
      TargetType.CLASS_EXTENDS
    };
  }

  /**
   * Returns the TypeCompounds (annotations) of the enclosing method for this parameter.
   *
   * @return the TypeCompounds (annotations) of the enclosing method for this parameter
   */
  @Override
  protected Iterable<Attribute.TypeCompound> getRawTypeAttributes() {
    return enclosingMethod.getRawTypeAttributes();
  }

  @Override
  protected Map<TargetClass, List<TypeCompound>> sift(
      Iterable<Attribute.TypeCompound> typeCompounds) {
    // this will sift out the annotations that do not have the right position index
    final Map<TargetClass, List<Attribute.TypeCompound>> targetClassToAnnos =
        super.sift(typeCompounds);

    final List<Attribute.TypeCompound> targeted = targetClassToAnnos.get(TargetClass.TARGETED);
    final List<Attribute.TypeCompound> valid = targetClassToAnnos.get(TargetClass.VALID);

    // if this is a lambdaParam, filter out from targeted those annos that apply to method
    // formal parameters if this is a method formal param, filter out from targeted those annos
    // that apply to lambdas
    int i = 0;
    while (i < targeted.size()) {
      final Tree onLambda = targeted.get(i).position.onLambda;
      if (onLambda == null) {
        if (!isLambdaParam) {
          ++i;
        } else {
          valid.add(targeted.remove(i));
        }

      } else {
        if (onLambda.equals(this.lambdaTree)) {
          ++i;
        } else {
          valid.add(targeted.remove(i));
        }
      }
    }

    return targetClassToAnnos;
  }

  /**
   * @param targeted type compounds with formal method parameter target types with parameter_index
   *     == getIndex
   */
  @Override
  protected void handleTargeted(final List<TypeCompound> targeted)
      throws UnexpectedAnnotationLocationException {

    final List<TypeCompound> formalParams = new ArrayList<>();
    Map<TargetType, List<TypeCompound>> targetToAnnos =
        ElementAnnotationUtil.partitionByTargetType(
            targeted, formalParams, TargetType.METHOD_RECEIVER);

    if (isReceiver(element)) {
      ElementAnnotationUtil.annotateViaTypeAnnoPosition(
          type, targetToAnnos.get(TargetType.METHOD_RECEIVER));

    } else {
      ElementAnnotationUtil.annotateViaTypeAnnoPosition(type, formalParams);
    }
  }

  /**
   * Returns true if element represents the receiver parameter of a method.
   *
   * @param element an element
   * @return true if element represents the receiver parameter of a method
   */
  private boolean isReceiver(final Element element) {
    return element.getKind() == ElementKind.PARAMETER
        && element.getSimpleName().contentEquals("this");
  }

  @Override
  protected boolean isAccepted() {
    return accepts(type, element);
  }

  /**
   * Return the enclosing MethodSymbol of the given element, throwing an exception of the symbol's
   * enclosing element is not a MethodSymbol.
   *
   * @param methodChildElem some element that is a child of a method typeDeclaration (e.g. a
   *     parameter or return type)
   * @return the MethodSymbol of the method containing methodChildElem
   */
  public static Symbol.MethodSymbol getParentMethod(final Element methodChildElem) {
    if (!(methodChildElem.getEnclosingElement() instanceof Symbol.MethodSymbol)) {
      throw new BugInCF(
          "Element is not a direct child of a MethodSymbol. Element ( "
              + methodChildElem
              + " parent ( "
              + methodChildElem.getEnclosingElement()
              + " ) ");
    }
    return (Symbol.MethodSymbol) methodChildElem.getEnclosingElement();
  }

  @Override
  public void extractAndApply() throws UnexpectedAnnotationLocationException {
    ElementAnnotationUtil.addDeclarationAnnotationsFromElement(
        type, element.getAnnotationMirrors());
    super.extractAndApply();
  }
}
