package org.checkerframework.framework.util.element;

import com.sun.tools.javac.code.Attribute.TypeCompound;
import com.sun.tools.javac.code.TargetType;
import java.util.ArrayList;
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.type.TypeKind;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable;
import org.checkerframework.framework.util.element.ElementAnnotationUtil.UnexpectedAnnotationLocationException;
import org.checkerframework.javacutil.BugInCF;

/**
 * Applies Element annotations to a single AnnotatedTypeVariable representing a type parameter.
 * Note, the index of IndexedElementAnnotationApplier refers to the type parameter's index in the
 * list that encloses it.
 */
abstract class TypeParamElementAnnotationApplier extends IndexedElementAnnotationApplier {

  /**
   * Returns true if element is a TYPE_PARAMETER.
   *
   * @param typeMirror ignored
   * @param element the element that might be a TYPE_PARAMETER
   * @return true if element is a TYPE_PARAMETER
   */
  public static boolean accepts(AnnotatedTypeMirror typeMirror, Element element) {
    return element.getKind() == ElementKind.TYPE_PARAMETER;
  }

  protected final AnnotatedTypeVariable typeParam;
  protected final AnnotatedTypeFactory typeFactory;

  /**
   * Returns target type that represents the location of the lower bound of element.
   *
   * @return target type that represents the location of the lower bound of element
   */
  protected abstract TargetType lowerBoundTarget();

  /**
   * Returns target type that represents the location of the upper bound of element.
   *
   * @return target type that represents the location of the upper bound of element
   */
  protected abstract TargetType upperBoundTarget();

  TypeParamElementAnnotationApplier(
      final AnnotatedTypeVariable type,
      final Element element,
      final AnnotatedTypeFactory typeFactory) {
    super(type, element);
    this.typeParam = type;
    this.typeFactory = typeFactory;
  }

  /**
   * Returns the lower bound and upper bound targets.
   *
   * @return the lower bound and upper bound targets
   */
  @Override
  protected TargetType[] annotatedTargets() {
    return new TargetType[] {lowerBoundTarget(), upperBoundTarget()};
  }

  /**
   * Returns the parameter_index of anno's TypeAnnotationPosition which will actually point to the
   * type parameter's index in its enclosing type parameter list.
   *
   * @return the parameter_index of anno's TypeAnnotationPosition which will actually point to the
   *     type parameter's index in its enclosing type parameter list
   */
  @Override
  public int getTypeCompoundIndex(final TypeCompound anno) {
    return anno.getPosition().parameter_index;
  }

  /**
   * @param targeted the list of annotations that were on the lower/upper bounds of the type
   *     parameter
   *     <p>Note: When handling type parameters we NEVER add primary annotations to the type
   *     parameter. Primary annotations are reserved for the use of a type parameter (e.g. @Nullable
   *     T t; )
   *     <p>If an annotation is present on the type parameter itself, it represents the lower-bound
   *     annotation of that type parameter. Any annotation on the extends bound of a type parameter
   *     is placed on that bound.
   */
  @Override
  protected void handleTargeted(final List<TypeCompound> targeted)
      throws UnexpectedAnnotationLocationException {
    final int paramIndex = getElementIndex();
    final List<TypeCompound> upperBoundAnnos = new ArrayList<>();
    final List<TypeCompound> lowerBoundAnnos = new ArrayList<>();

    for (final TypeCompound anno : targeted) {
      final AnnotationMirror aliasedAnno = typeFactory.canonicalAnnotation(anno);
      final AnnotationMirror canonicalAnno = (aliasedAnno != null) ? aliasedAnno : anno;

      if (anno.position.parameter_index != paramIndex
          || !typeFactory.isSupportedQualifier(canonicalAnno)) {
        continue;
      }

      if (ElementAnnotationUtil.isOnComponentType(anno)) {
        applyComponentAnnotation(anno);

      } else if (anno.position.type == upperBoundTarget()) {
        upperBoundAnnos.add(anno);

      } else {
        lowerBoundAnnos.add(anno);
      }
    }

    applyLowerBounds(lowerBoundAnnos);
    applyUpperBounds(upperBoundAnnos);
  }

  /**
   * Applies a list of annotations to the upperBound of the type parameter. If the type of the upper
   * bound is an intersection we must first find the correct location for each annotation.
   */
  private void applyUpperBounds(final List<TypeCompound> upperBounds) {
    if (!upperBounds.isEmpty()) {
      final AnnotatedTypeMirror upperBoundType = typeParam.getUpperBound();

      if (upperBoundType.getKind() == TypeKind.INTERSECTION) {

        final List<AnnotatedTypeMirror> bounds =
            ((AnnotatedIntersectionType) upperBoundType).getBounds();
        final int boundIndexOffset = ElementAnnotationUtil.getBoundIndexOffset(bounds);

        for (final TypeCompound anno : upperBounds) {
          final int boundIndex = anno.position.bound_index + boundIndexOffset;

          if (boundIndex < 0 || boundIndex > bounds.size()) {
            throw new BugInCF(
                "Invalid bound index on element annotation ( "
                    + anno
                    + " ) "
                    + "for type ( "
                    + typeParam
                    + " ) with "
                    + "upper bound ( "
                    + typeParam.getUpperBound()
                    + " ) "
                    + "and boundIndex( "
                    + boundIndex
                    + " ) ");
          }

          bounds.get(boundIndex).replaceAnnotation(anno); // TODO: WHY NOT ADD?
        }
        ((AnnotatedIntersectionType) upperBoundType).copyIntersectionBoundAnnotations();

      } else {
        upperBoundType.addAnnotations(upperBounds);
      }
    }
  }

  /**
   * In the event of multiple annotations on an AnnotatedNullType lower bound we want to preserve
   * the multiple annotations so that a type.invalid error is issued later.
   *
   * @param annos the annotations to add to the lower bound
   */
  private void applyLowerBounds(final List<? extends AnnotationMirror> annos) {
    if (!annos.isEmpty()) {
      final AnnotatedTypeMirror lowerBound = typeParam.getLowerBound();

      for (AnnotationMirror anno : annos) {
        lowerBound.addAnnotation(anno);
      }
    }
  }

  private void addAnnotationToMap(
      final AnnotatedTypeMirror type,
      final TypeCompound anno,
      final Map<AnnotatedTypeMirror, List<TypeCompound>> typeToAnnos) {
    List<TypeCompound> annoList = typeToAnnos.computeIfAbsent(type, __ -> new ArrayList<>());
    annoList.add(anno);
  }

  private void applyComponentAnnotation(final TypeCompound anno)
      throws UnexpectedAnnotationLocationException {
    final AnnotatedTypeMirror upperBoundType = typeParam.getUpperBound();

    Map<AnnotatedTypeMirror, List<TypeCompound>> typeToAnnotations = new HashMap<>();

    if (anno.position.type == upperBoundTarget()) {

      if (upperBoundType.getKind() == TypeKind.INTERSECTION) {
        final List<AnnotatedTypeMirror> bounds =
            ((AnnotatedIntersectionType) upperBoundType).getBounds();
        final int boundIndex =
            anno.position.bound_index + ElementAnnotationUtil.getBoundIndexOffset(bounds);

        if (boundIndex < 0 || boundIndex > bounds.size()) {
          throw new BugInCF(
              "Invalid bound index on element annotation ( "
                  + anno
                  + " ) "
                  + "for type ( "
                  + typeParam
                  + " ) with upper bound ( "
                  + typeParam.getUpperBound()
                  + " )");
        }
        addAnnotationToMap(bounds.get(boundIndex), anno, typeToAnnotations);

      } else {
        addAnnotationToMap(upperBoundType, anno, typeToAnnotations);
      }

    } else {
      addAnnotationToMap(typeParam.getLowerBound(), anno, typeToAnnotations);
    }

    for (Map.Entry<AnnotatedTypeMirror, List<TypeCompound>> typeToAnno :
        typeToAnnotations.entrySet()) {
      ElementAnnotationUtil.annotateViaTypeAnnoPosition(typeToAnno.getKey(), typeToAnno.getValue());
    }
  }
}
