package org.checkerframework.checker.calledmethods.builder;

import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.VariableTree;
import java.beans.Introspector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import org.checkerframework.checker.calledmethods.CalledMethodsAnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.ElementUtils;

/**
 * Lombok support for the Called Methods Checker. This class adds CalledMethods annotations to the
 * code generated by Lombok.
 */
public class LombokSupport implements BuilderFrameworkSupport {

  /** The type factory. */
  private CalledMethodsAnnotatedTypeFactory atypeFactory;

  /**
   * Create a new LombokSupport.
   *
   * @param atypeFactory the typechecker's type factory
   */
  public LombokSupport(CalledMethodsAnnotatedTypeFactory atypeFactory) {
    this.atypeFactory = atypeFactory;
  }

  // The list is copied from lombok.core.handlers.HandlerUtil. The list cannot be used from that
  // class directly because Lombok does not provide class files for its own implementation, to
  // prevent itself from being accidentally added to clients' compile classpaths. This design
  // decision means that it is impossible to depend directly on Lombok internals.
  /** The list of annotations that Lombok treats as non-null. */
  public static final List<String> NONNULL_ANNOTATIONS =
      Collections.unmodifiableList(
          Arrays.asList(
              "android.annotation.NonNull",
              "android.support.annotation.NonNull",
              "com.sun.istack.internal.NotNull",
              "edu.umd.cs.findbugs.annotations.NonNull",
              "javax.annotation.Nonnull",
              // "javax.validation.constraints.NotNull", // The field might contain a
              // null value until it is persisted.
              "lombok.NonNull",
              "org.checkerframework.checker.nullness.qual.NonNull",
              "org.eclipse.jdt.annotation.NonNull",
              "org.eclipse.jgit.annotations.NonNull",
              "org.jetbrains.annotations.NotNull",
              "org.jmlspecs.annotation.NonNull",
              "org.netbeans.api.annotations.common.NonNull",
              "org.springframework.lang.NonNull"));

  /**
   * A map from elements that have a lombok.Builder.Default annotation to the simple property name
   * that should be treated as defaulted.
   *
   * <p>This cache is kept because the usual method for checking that an element has been defaulted
   * (calling declarationFromElement and examining the resulting VariableTree) only works if a
   * corresponding Tree is available (for code that is only available as bytecode, no such Tree is
   * available and that method returns null). See the code in {@link
   * #getLombokRequiredProperties(Element)} that handles fields.
   */
  private final Map<Element, Name> defaultedElements = new HashMap<>(2);

  @Override
  public boolean isBuilderBuildMethod(ExecutableElement candidateBuildElement) {
    TypeElement candidateGeneratedBuilderElement =
        (TypeElement) candidateBuildElement.getEnclosingElement();

    if ((ElementUtils.hasAnnotation(candidateGeneratedBuilderElement, "lombok.Generated")
            || ElementUtils.hasAnnotation(candidateBuildElement, "lombok.Generated"))
        && candidateGeneratedBuilderElement.getSimpleName().toString().endsWith("Builder")) {
      return candidateBuildElement.getSimpleName().contentEquals("build");
    }
    return false;
  }

  @Override
  public void handleBuilderBuildMethod(AnnotatedExecutableType builderBuildType) {
    ExecutableElement buildElement = builderBuildType.getElement();

    TypeElement generatedBuilderElement = (TypeElement) buildElement.getEnclosingElement();
    // The class with the @lombok.Builder annotation...
    Element annotatedWithBuilderElement = generatedBuilderElement.getEnclosingElement();

    List<String> requiredProperties = getLombokRequiredProperties(annotatedWithBuilderElement);
    AnnotationMirror newCalledMethodsAnno =
        atypeFactory.createAccumulatorAnnotation(requiredProperties);
    builderBuildType.getReceiverType().addAnnotation(newCalledMethodsAnno);
  }

  @Override
  public boolean isToBuilderMethod(ExecutableElement candidateToBuilderElement) {
    return candidateToBuilderElement.getSimpleName().contentEquals("toBuilder")
        && (ElementUtils.hasAnnotation(candidateToBuilderElement, "lombok.Generated")
            || ElementUtils.hasAnnotation(
                candidateToBuilderElement.getEnclosingElement(), "lombok.Generated"));
  }

  @Override
  public void handleToBuilderMethod(AnnotatedExecutableType toBuilderType) {
    AnnotatedTypeMirror returnType = toBuilderType.getReturnType();
    ExecutableElement buildElement = toBuilderType.getElement();
    TypeElement generatedBuilderElement = (TypeElement) buildElement.getEnclosingElement();
    handleToBuilderType(returnType, generatedBuilderElement);
  }

  /**
   * Add, to a type, a CalledMethods annotation that states that all required setters have been
   * called. The type can be the return type of toBuilder or of the corresponding generated "copy"
   * constructor.
   *
   * @param type type to update
   * @param classElement corresponding AutoValue class
   */
  private void handleToBuilderType(AnnotatedTypeMirror type, Element classElement) {
    List<String> requiredProperties = getLombokRequiredProperties(classElement);
    AnnotationMirror calledMethodsAnno =
        atypeFactory.createAccumulatorAnnotation(requiredProperties);
    type.replaceAnnotation(calledMethodsAnno);
  }

  /**
   * Computes the required properties of a @lombok.Builder class, i.e., the names of the fields
   * with @lombok.NonNull annotations.
   *
   * @param lombokClassElement the class with the @lombok.Builder annotation
   * @return a list of required property names
   */
  private List<String> getLombokRequiredProperties(final Element lombokClassElement) {
    List<String> requiredPropertyNames = new ArrayList<>();
    List<String> defaultedPropertyNames = new ArrayList<>();
    for (Element member : lombokClassElement.getEnclosedElements()) {
      if (member.getKind() == ElementKind.FIELD) {
        // Lombok never generates non-null fields with initializers in builders, unless the field is
        // annotated with @Default or @Singular, which are handled elsewhere.  So, this code doesn't
        // need to consider whether the field has or does not have initializers.
        for (AnnotationMirror anm :
            atypeFactory.getElementUtils().getAllAnnotationMirrors(member)) {
          if (NONNULL_ANNOTATIONS.contains(AnnotationUtils.annotationName(anm))) {
            requiredPropertyNames.add(member.getSimpleName().toString());
          }
        }
      } else if (member.getKind() == ElementKind.METHOD
          && ElementUtils.hasAnnotation(member, "lombok.Generated")) {
        String methodName = member.getSimpleName().toString();
        // If a field foo has an @Builder.Default annotation, Lombok always generates a
        // method called $default$foo.
        if (methodName.startsWith("$default$")) {
          String propName = methodName.substring(9); // $default$ has 9 characters
          defaultedPropertyNames.add(propName);
        }
      } else if (member.getKind().isClass() && member.toString().endsWith("Builder")) {
        // Note that the test above will fail to catch builders generated by Lombok that have custom
        // names using the builderClassName attribute. TODO: find a way to handle such builders too.

        // If a field bar has an @Singular annotation, Lombok always generates a method called
        // clearBar in the builder class itself. Therefore, search the builder for such a method,
        // and extract the appropriate property name to treat as defaulted.
        for (Element builderMember : member.getEnclosedElements()) {
          if (builderMember.getKind() == ElementKind.METHOD
              && ElementUtils.hasAnnotation(builderMember, "lombok.Generated")) {
            String methodName = builderMember.getSimpleName().toString();
            if (methodName.startsWith("clear")) {
              String propName =
                  Introspector.decapitalize(methodName.substring(5)); // clear has 5 characters
              defaultedPropertyNames.add(propName);
            }
          } else if (builderMember.getKind() == ElementKind.FIELD) {
            VariableTree variableTree =
                (VariableTree) atypeFactory.declarationFromElement(builderMember);
            if (variableTree != null && variableTree.getInitializer() != null) {
              Name propName = variableTree.getName();
              defaultedPropertyNames.add(propName.toString());
              defaultedElements.put(builderMember, propName);
            } else if (defaultedElements.containsKey(builderMember)) {
              defaultedPropertyNames.add(defaultedElements.get(builderMember).toString());
            }
          }
        }
      }
    }
    requiredPropertyNames.removeAll(defaultedPropertyNames);
    return requiredPropertyNames;
  }

  @Override
  public void handleConstructor(NewClassTree tree, AnnotatedTypeMirror type) {
    return;
  }
}
