package org.checkerframework.framework.type.typeannotator;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
import org.checkerframework.checker.signature.qual.CanonicalName;
import org.checkerframework.framework.qual.DefaultQualifierForUse;
import org.checkerframework.framework.qual.NoDefaultQualifierForUse;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType;
import org.checkerframework.framework.util.AnnotationMirrorSet;
import org.checkerframework.javacutil.AnnotationBuilder;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.CollectionUtils;
import org.checkerframework.javacutil.TreeUtils;

/** Implements support for {@link DefaultQualifierForUse} and {@link NoDefaultQualifierForUse}. */
public class DefaultQualifierForUseTypeAnnotator extends TypeAnnotator {

  /** The DefaultQualifierForUse.value field/element. */
  private ExecutableElement defaultQualifierForUseValueElement;
  /** The NoDefaultQualifierForUse.value field/element. */
  private ExecutableElement noDefaultQualifierForUseValueElement;

  /**
   * Creates an DefaultQualifierForUseTypeAnnotator for {@code typeFactory}.
   *
   * @param typeFactory the type factory
   */
  public DefaultQualifierForUseTypeAnnotator(AnnotatedTypeFactory typeFactory) {
    super(typeFactory);
    ProcessingEnvironment processingEnv = typeFactory.getProcessingEnv();
    defaultQualifierForUseValueElement =
        TreeUtils.getMethod(DefaultQualifierForUse.class, "value", 0, processingEnv);
    noDefaultQualifierForUseValueElement =
        TreeUtils.getMethod(NoDefaultQualifierForUse.class, "value", 0, processingEnv);
  }

  @Override
  public Void visitDeclared(AnnotatedDeclaredType type, Void aVoid) {
    Element element = type.getUnderlyingType().asElement();
    Set<AnnotationMirror> annosToApply = getDefaultAnnosForUses(element);
    type.addMissingAnnotations(annosToApply);
    return super.visitDeclared(type, aVoid);
  }

  /**
   * Cache of elements to the set of annotations that should be applied to unannotated uses of the
   * element.
   */
  protected Map<Element, Set<AnnotationMirror>> elementToDefaults =
      CollectionUtils.createLRUCache(100);

  /** Clears all caches. */
  public void clearCache() {
    elementToDefaults.clear();
  }

  /** Returns the set of qualifiers that should be applied to unannotated uses of this element. */
  protected Set<AnnotationMirror> getDefaultAnnosForUses(Element element) {
    if (typeFactory.shouldCache && elementToDefaults.containsKey(element)) {
      return elementToDefaults.get(element);
    }
    Set<AnnotationMirror> explictAnnos = getExplicitAnnos(element);
    Set<AnnotationMirror> defaultAnnos = getDefaultQualifierForUses(element);
    Set<AnnotationMirror> noDefaultAnnos = getHierarchiesNoDefault(element);
    AnnotationMirrorSet annosToApply = new AnnotationMirrorSet();

    for (AnnotationMirror top : typeFactory.getQualifierHierarchy().getTopAnnotations()) {
      if (AnnotationUtils.containsSame(noDefaultAnnos, top)) {
        continue;
      }
      AnnotationMirror defaultAnno =
          typeFactory.getQualifierHierarchy().findAnnotationInHierarchy(defaultAnnos, top);
      if (defaultAnno != null) {
        annosToApply.add(defaultAnno);
      } else {
        AnnotationMirror explict =
            typeFactory.getQualifierHierarchy().findAnnotationInHierarchy(explictAnnos, top);
        if (explict != null) {
          annosToApply.add(explict);
        }
      }
    }
    // If parsing stub files, then the annosToApply is incomplete, so don't cache them.
    if (typeFactory.shouldCache
        && !typeFactory.stubTypes.isParsing()
        && !typeFactory.ajavaTypes.isParsing()) {
      elementToDefaults.put(element, annosToApply);
    }
    return annosToApply;
  }

  /** Return the annotations explicitly written on the element. */
  protected Set<AnnotationMirror> getExplicitAnnos(Element element) {
    AnnotatedTypeMirror explicitAnnoOnDecl = typeFactory.fromElement(element);
    return explicitAnnoOnDecl.getAnnotations();
  }

  /**
   * Return the default qualifiers for uses of {@code element} as specified by a {@link
   * DefaultQualifierForUse} annotation.
   *
   * <p>Subclasses may override to use an annotation other than {@link DefaultQualifierForUse}.
   *
   * @param element an element
   * @return the default qualifiers for uses of {@code element}
   */
  protected Set<AnnotationMirror> getDefaultQualifierForUses(Element element) {
    AnnotationMirror defaultQualifier =
        typeFactory.getDeclAnnotation(element, DefaultQualifierForUse.class);
    if (defaultQualifier == null) {
      return Collections.emptySet();
    }
    return supportedAnnosFromAnnotationMirror(
        AnnotationUtils.getElementValueClassNames(
            defaultQualifier, defaultQualifierForUseValueElement));
  }

  /**
   * Returns top annotations in hierarchies for which no default for use qualifier should be added.
   */
  protected Set<AnnotationMirror> getHierarchiesNoDefault(Element element) {
    AnnotationMirror noDefaultQualifier =
        typeFactory.getDeclAnnotation(element, NoDefaultQualifierForUse.class);
    if (noDefaultQualifier == null) {
      return Collections.emptySet();
    }
    return supportedAnnosFromAnnotationMirror(
        AnnotationUtils.getElementValueClassNames(
            noDefaultQualifier, noDefaultQualifierForUseValueElement));
  }

  /**
   * Returns the set of qualifiers supported by this type system from the value element of {@code
   * annotationMirror}.
   *
   * @param annotationMirror a non-null annotation with a value element that is an array of
   *     annotation classes
   * @return the set of qualifiers supported by this type system from the value element of {@code
   *     annotationMirror}
   * @deprecated use {@link #supportedAnnosFromAnnotationMirror(List)}
   */
  @SuppressWarnings("deprecation") // This method is itself deprecated.
  @Deprecated // 2021-03-21
  protected final AnnotationMirrorSet supportedAnnosFromAnnotationMirror(
      AnnotationMirror annotationMirror) {
    return supportedAnnosFromAnnotationMirror(
        AnnotationUtils.getElementValueClassNames(annotationMirror, "value", true));
  }

  /**
   * Returns the set of qualifiers supported by this type system from the value element of {@code
   * annotationMirror}.
   *
   * @param annoClassNames a list of annotation class names
   * @return the set of qualifiers supported by this type system from the value element of {@code
   *     annotationMirror}
   */
  protected final AnnotationMirrorSet supportedAnnosFromAnnotationMirror(
      List<@CanonicalName Name> annoClassNames) {
    AnnotationMirrorSet supportAnnos = new AnnotationMirrorSet();
    for (Name annoName : annoClassNames) {
      AnnotationMirror anno = AnnotationBuilder.fromName(typeFactory.getElementUtils(), annoName);
      if (typeFactory.isSupportedQualifier(anno)) {
        supportAnnos.add(anno);
      }
    }
    return supportAnnos;
  }
}
