package org.checkerframework.framework.type;

import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.util.Elements;
import org.checkerframework.checker.initialization.qual.UnderInitialization;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
import org.checkerframework.checker.signature.qual.CanonicalName;
import org.checkerframework.framework.qual.AnnotatedFor;
import org.checkerframework.framework.util.DefaultQualifierKindHierarchy;
import org.checkerframework.framework.util.QualifierKind;
import org.checkerframework.framework.util.QualifierKindHierarchy;
import org.checkerframework.javacutil.AnnotationBuilder;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.BugInCF;
import org.checkerframework.javacutil.TypeSystemError;

/**
 * A {@link QualifierHierarchy} where qualifiers may be represented by annotations with elements.
 *
 * <p>ElementQualifierHierarchy uses a {@link QualifierKindHierarchy} to model the relationships
 * between qualifiers. (By contrast, {@link MostlyNoElementQualifierHierarchy} uses the {@link
 * QualifierKindHierarchy} to implement {@code isSubtype}, {@code leastUpperBound}, and {@code
 * greatestLowerBound} methods for qualifiers without elements.)
 *
 * <p>Subclasses can override {@link #createQualifierKindHierarchy(Collection)} to return a subclass
 * of QualifierKindHierarchy.
 */
@AnnotatedFor("nullness")
public abstract class ElementQualifierHierarchy implements QualifierHierarchy {

  /** {@link org.checkerframework.javacutil.ElementUtils}. */
  private Elements elements;

  /** {@link QualifierKindHierarchy}. */
  protected final QualifierKindHierarchy qualifierKindHierarchy;

  // The following fields duplicate information in qualifierKindHierarchy, but using
  // AnnotationMirrors instead of QualifierKinds.

  /** A mapping from top QualifierKinds to their corresponding AnnotationMirror. */
  protected final Map<QualifierKind, AnnotationMirror> topsMap;

  /** The set of top annotation mirrors. */
  protected final Set<AnnotationMirror> tops;

  /** A mapping from bottom QualifierKinds to their corresponding AnnotationMirror. */
  protected final Map<QualifierKind, AnnotationMirror> bottomsMap;

  /** The set of bottom annotation mirrors. */
  protected final Set<AnnotationMirror> bottoms;

  /**
   * A mapping from QualifierKind to AnnotationMirror for all qualifiers whose annotations do not
   * have elements.
   */
  protected final Map<QualifierKind, AnnotationMirror> kindToElementlessQualifier;

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

    this.topsMap = Collections.unmodifiableMap(createTopsMap());
    this.tops = AnnotationUtils.createUnmodifiableAnnotationSet(topsMap.values());

    this.bottomsMap = Collections.unmodifiableMap(createBottomsMap());
    this.bottoms = AnnotationUtils.createUnmodifiableAnnotationSet(bottomsMap.values());

    this.kindToElementlessQualifier = createElementlessQualifierMap();
  }

  @Override
  public boolean isValid() {
    for (AnnotationMirror top : tops) {
      // This throws an error if poly is a qualifier that has an element.
      getPolymorphicAnnotation(top);
    }
    return true;
  }

  /**
   * Create the {@link QualifierKindHierarchy}. (Subclasses may override to return a subclass of
   * QualifierKindHierarchy.)
   *
   * @param qualifierClasses classes of annotations that are the qualifiers for this hierarchy
   * @return the newly created qualifier kind hierarchy
   */
  protected QualifierKindHierarchy createQualifierKindHierarchy(
      @UnderInitialization ElementQualifierHierarchy this,
      Collection<Class<? extends Annotation>> qualifierClasses) {
    return new DefaultQualifierKindHierarchy(qualifierClasses);
  }

  /**
   * Creates a mapping from QualifierKind to AnnotationMirror for all qualifiers whose annotations
   * do not have elements.
   *
   * @return the mapping
   */
  @RequiresNonNull({"this.qualifierKindHierarchy", "this.elements"})
  protected Map<QualifierKind, AnnotationMirror> createElementlessQualifierMap(
      @UnderInitialization ElementQualifierHierarchy this) {
    Map<QualifierKind, AnnotationMirror> quals = new TreeMap<>();
    for (QualifierKind kind : qualifierKindHierarchy.allQualifierKinds()) {
      if (!kind.hasElements()) {
        quals.put(kind, AnnotationBuilder.fromClass(elements, kind.getAnnotationClass()));
      }
    }
    return Collections.unmodifiableMap(quals);
  }

  /**
   * Creates a mapping from QualifierKind to AnnotationMirror, where the QualifierKind is top and
   * the AnnotationMirror is top in their respective hierarchies.
   *
   * <p>This implementation works if the top annotation has no elements, or if it has elements,
   * provides a default, and that default is the top. Otherwise, subclasses must override this.
   *
   * @return a mapping from top QualifierKind to top AnnotationMirror
   */
  @RequiresNonNull({"this.qualifierKindHierarchy", "this.elements"})
  protected Map<QualifierKind, AnnotationMirror> createTopsMap(
      @UnderInitialization ElementQualifierHierarchy this) {
    Map<QualifierKind, AnnotationMirror> topsMap = new TreeMap<>();
    for (QualifierKind kind : qualifierKindHierarchy.getTops()) {
      topsMap.put(kind, AnnotationBuilder.fromClass(elements, kind.getAnnotationClass()));
    }
    return topsMap;
  }

  /**
   * Creates a mapping from QualifierKind to AnnotationMirror, where the QualifierKind is bottom and
   * the AnnotationMirror is bottom in their respective hierarchies.
   *
   * <p>This implementation works if the bottom annotation has no elements, or if it has elements,
   * provides a default, and that default is the bottom. Otherwise, subclasses must override this.
   *
   * @return a mapping from bottom QualifierKind to bottom AnnotationMirror
   */
  @RequiresNonNull({"this.qualifierKindHierarchy", "this.elements"})
  protected Map<QualifierKind, AnnotationMirror> createBottomsMap(
      @UnderInitialization ElementQualifierHierarchy this) {
    Map<QualifierKind, AnnotationMirror> bottomsMap = new TreeMap<>();
    for (QualifierKind kind : qualifierKindHierarchy.getBottoms()) {
      bottomsMap.put(kind, AnnotationBuilder.fromClass(elements, kind.getAnnotationClass()));
    }
    return bottomsMap;
  }

  /**
   * Returns the qualifier kind for the given annotation.
   *
   * @param anno annotation mirror
   * @return the qualifier kind for the given annotation
   */
  protected QualifierKind getQualifierKind(AnnotationMirror anno) {
    String name = AnnotationUtils.annotationName(anno);
    return getQualifierKind(name);
  }

  /**
   * Returns the qualifier kind for the annotation with the canonical name {@code name}.
   *
   * @param name fully qualified annotation name
   * @return the qualifier kind for the annotation named {@code name}
   */
  protected QualifierKind getQualifierKind(@CanonicalName String name) {
    QualifierKind kind = qualifierKindHierarchy.getQualifierKind(name);
    if (kind == null) {
      throw new BugInCF("QualifierKind %s not in hierarchy", name);
    }
    return kind;
  }

  @Override
  public Set<? extends AnnotationMirror> getTopAnnotations() {
    return tops;
  }

  @Override
  public AnnotationMirror getTopAnnotation(AnnotationMirror start) {
    QualifierKind kind = getQualifierKind(start);
    @SuppressWarnings("nullness:assignment") // All tops are a key for topsMap.
    @NonNull AnnotationMirror result = topsMap.get(kind.getTop());
    return result;
  }

  @Override
  public Set<? extends AnnotationMirror> getBottomAnnotations() {
    return bottoms;
  }

  @Override
  public @Nullable AnnotationMirror getPolymorphicAnnotation(AnnotationMirror start) {
    QualifierKind polyKind = getQualifierKind(start).getPolymorphic();
    if (polyKind == null) {
      return null;
    }
    AnnotationMirror poly = kindToElementlessQualifier.get(polyKind);
    if (poly == null) {
      throw new TypeSystemError(
          "Poly %s has an element. Override ElementQualifierHierarchy#getPolymorphicAnnotation.",
          polyKind);
    }
    return poly;
  }

  @Override
  public boolean isPolymorphicQualifier(AnnotationMirror qualifier) {
    return getQualifierKind(qualifier).isPoly();
  }

  @Override
  public AnnotationMirror getBottomAnnotation(AnnotationMirror start) {
    QualifierKind kind = getQualifierKind(start);
    @SuppressWarnings("nullness:assignment") // All bottoms are keys for bottomsMap.
    @NonNull AnnotationMirror result = bottomsMap.get(kind.getBottom());
    return result;
  }

  @Override
  public @Nullable AnnotationMirror findAnnotationInSameHierarchy(
      Collection<? extends AnnotationMirror> annos, AnnotationMirror annotationMirror) {
    QualifierKind kind = getQualifierKind(annotationMirror);
    for (AnnotationMirror candidate : annos) {
      QualifierKind candidateKind = getQualifierKind(candidate);
      if (candidateKind.isInSameHierarchyAs(kind)) {
        return candidate;
      }
    }
    return null;
  }

  @Override
  public @Nullable AnnotationMirror findAnnotationInHierarchy(
      Collection<? extends AnnotationMirror> annos, AnnotationMirror top) {
    return findAnnotationInSameHierarchy(annos, top);
  }
}
