package org.checkerframework.checker.interning;

import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.CompoundAssignmentTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.TypeCastTree;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import org.checkerframework.checker.interning.qual.FindDistinct;
import org.checkerframework.checker.interning.qual.InternMethod;
import org.checkerframework.checker.interning.qual.Interned;
import org.checkerframework.checker.interning.qual.InternedDistinct;
import org.checkerframework.checker.interning.qual.PolyInterned;
import org.checkerframework.checker.interning.qual.UnknownInterned;
import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.framework.qual.DefaultQualifier;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType;
import org.checkerframework.framework.type.treeannotator.ListTreeAnnotator;
import org.checkerframework.framework.type.treeannotator.TreeAnnotator;
import org.checkerframework.framework.type.typeannotator.DefaultQualifierForUseTypeAnnotator;
import org.checkerframework.framework.type.typeannotator.ListTypeAnnotator;
import org.checkerframework.framework.type.typeannotator.TypeAnnotator;
import org.checkerframework.framework.util.AnnotationMirrorSet;
import org.checkerframework.javacutil.AnnotationBuilder;
import org.checkerframework.javacutil.ElementUtils;
import org.checkerframework.javacutil.TreeUtils;

/**
 * An {@link AnnotatedTypeFactory} that accounts for the properties of the Interned type system.
 * This type factory will add the {@link Interned} annotation to a type if the input:
 *
 * <ol>
 *   <li value="1">is a String literal
 *   <li value="2">is a class literal
 *   <li value="3">has an enum type
 *   <li value="4">has a primitive type
 *   <li value="5">has the type java.lang.Class
 *   <li value="6">is a use of a class declared to be @Interned
 * </ol>
 *
 * This type factory adds {@link InternedDistinct} to formal parameters that have a {@code @}{@link
 * FindDistinct} declaration annotation. (TODO: That isn't a good implementation, because it is not
 * accurate: the value might be equals() to some other Java value. More seriously, it permits too
 * much. Writing {@code @FindDistinct} should permit equality tests on the given formal parameter,
 * but should not (for example) permit the formal parameter to be assigned into an
 * {@code @InternedDistinct} location.)
 *
 * <p>This factory extends {@link BaseAnnotatedTypeFactory} and inherits its functionality,
 * including: flow-sensitive qualifier inference, qualifier polymorphism (of {@link PolyInterned}),
 * implicit annotations via {@link org.checkerframework.framework.qual.DefaultFor} on {@link
 * Interned} (to handle cases 1, 2, 4), and user-specified defaults via {@link DefaultQualifier}.
 * Case 5 is handled by the stub library.
 */
public class InterningAnnotatedTypeFactory extends BaseAnnotatedTypeFactory {

  /** The {@link UnknownInterned} annotation. */
  final AnnotationMirror TOP = AnnotationBuilder.fromClass(elements, UnknownInterned.class);
  /** The {@link Interned} annotation. */
  final AnnotationMirror INTERNED = AnnotationBuilder.fromClass(elements, Interned.class);
  /** The {@link InternedDistinct} annotation. */
  final AnnotationMirror INTERNED_DISTINCT =
      AnnotationBuilder.fromClass(elements, InternedDistinct.class);

  /**
   * Creates a new {@link InterningAnnotatedTypeFactory} that operates on a particular AST.
   *
   * @param checker the checker to use
   */
  public InterningAnnotatedTypeFactory(BaseTypeChecker checker) {
    super(checker);

    // If you update the following, also update ../../../../../docs/manual/interning-checker.tex
    addAliasedTypeAnnotation("com.sun.istack.internal.Interned", INTERNED);

    this.postInit();
  }

  @Override
  protected DefaultQualifierForUseTypeAnnotator createDefaultForUseTypeAnnotator() {
    return new InterningDefaultQualifierForUseTypeAnnotator(this);
  }

  /**
   * Does not add defaults for type uses on constructor results. Constructor results should be
   * {@code @UnknownInterned} by default.
   */
  static class InterningDefaultQualifierForUseTypeAnnotator
      extends DefaultQualifierForUseTypeAnnotator {

    public InterningDefaultQualifierForUseTypeAnnotator(AnnotatedTypeFactory typeFactory) {
      super(typeFactory);
    }

    @Override
    public Void visitExecutable(AnnotatedExecutableType type, Void p) {
      MethodSymbol methodElt = (MethodSymbol) type.getElement();

      if (methodElt == null || methodElt.getKind() != ElementKind.CONSTRUCTOR) {
        // Annotate method returns, not constructors.
        scan(type.getReturnType(), p);
      }
      if (type.getReceiverType() != null
          // Intern method may be called on UnknownInterned object, so its receiver should
          // not be annotated as @Interned.
          && typeFactory.getDeclAnnotation(methodElt, InternMethod.class) == null) {
        scanAndReduce(type.getReceiverType(), p, null);
      }
      scanAndReduce(type.getParameterTypes(), p, null);
      scanAndReduce(type.getThrownTypes(), p, null);
      scanAndReduce(type.getTypeVariables(), p, null);
      return null;
    }
  }

  @Override
  public Set<AnnotationMirror> getTypeDeclarationBounds(TypeMirror typeMirror) {
    if (typeMirror.getKind() == TypeKind.DECLARED
        && ((DeclaredType) typeMirror).asElement().getKind() == ElementKind.ENUM) {
      return AnnotationMirrorSet.singleElementSet(INTERNED);
    }
    return super.getTypeDeclarationBounds(typeMirror);
  }

  @Override
  protected TreeAnnotator createTreeAnnotator() {
    return new ListTreeAnnotator(super.createTreeAnnotator(), new InterningTreeAnnotator(this));
  }

  @Override
  protected TypeAnnotator createTypeAnnotator() {
    return new ListTypeAnnotator(new InterningTypeAnnotator(this), super.createTypeAnnotator());
  }

  @Override
  public void addComputedTypeAnnotations(Tree tree, AnnotatedTypeMirror type, boolean useFlow) {
    Element element = TreeUtils.elementFromTree(tree);
    if (!type.isAnnotatedInHierarchy(INTERNED) && ElementUtils.isCompileTimeConstant(element)) {
      type.addAnnotation(INTERNED);
    }
    super.addComputedTypeAnnotations(tree, type, useFlow);
  }

  @Override
  public void addComputedTypeAnnotations(Element element, AnnotatedTypeMirror type) {
    if (!type.isAnnotatedInHierarchy(INTERNED) && ElementUtils.isCompileTimeConstant(element)) {
      type.addAnnotation(INTERNED);
    }
    super.addComputedTypeAnnotations(element, type);
  }

  /** A class for adding annotations based on tree. */
  private class InterningTreeAnnotator extends TreeAnnotator {

    InterningTreeAnnotator(InterningAnnotatedTypeFactory atypeFactory) {
      super(atypeFactory);
    }

    @Override
    public Void visitBinary(BinaryTree node, AnnotatedTypeMirror type) {
      if (TreeUtils.isCompileTimeString(node)) {
        type.replaceAnnotation(INTERNED);
      } else if (TreeUtils.isStringConcatenation(node)) {
        type.replaceAnnotation(TOP);
      } else if (type.getKind().isPrimitive()
          || node.getKind() == Tree.Kind.EQUAL_TO
          || node.getKind() == Tree.Kind.NOT_EQUAL_TO) {
        type.replaceAnnotation(INTERNED);
      } else {
        type.replaceAnnotation(TOP);
      }
      return super.visitBinary(node, type);
    }

    /* Compound assignments never result in an interned result.
     */
    @Override
    public Void visitCompoundAssignment(CompoundAssignmentTree node, AnnotatedTypeMirror type) {
      type.replaceAnnotation(TOP);
      return super.visitCompoundAssignment(node, type);
    }

    @Override
    public Void visitTypeCast(TypeCastTree node, AnnotatedTypeMirror type) {
      if (TreeUtils.typeOf(node.getType()).getKind().isPrimitive()) {
        type.replaceAnnotation(INTERNED);
      }
      return super.visitTypeCast(node, type);
    }

    @Override
    public Void visitIdentifier(IdentifierTree node, AnnotatedTypeMirror type) {
      Element e = TreeUtils.elementFromTree(node);
      if (atypeFactory.getDeclAnnotation(e, FindDistinct.class) != null) {
        // TODO: See note above about this being a poor implementation.
        type.replaceAnnotation(INTERNED_DISTINCT);
      }
      return super.visitIdentifier(node, type);
    }
  }

  /** Adds @Interned to enum types. */
  private class InterningTypeAnnotator extends TypeAnnotator {

    InterningTypeAnnotator(InterningAnnotatedTypeFactory atypeFactory) {
      super(atypeFactory);
    }

    @Override
    public Void visitDeclared(AnnotatedDeclaredType t, Void p) {
      // case 3: Enum types, and the Enum class itself, are interned
      Element elt = t.getUnderlyingType().asElement();
      assert elt != null;
      if (elt.getKind() == ElementKind.ENUM) {
        t.replaceAnnotation(INTERNED);
      }
      return super.visitDeclared(t, p);
    }
  }

  /**
   * Unbox type and replace any interning type annotations with @Interned since all primitives can
   * safely use ==. See case 4 in the class comments.
   */
  @Override
  public AnnotatedPrimitiveType getUnboxedType(AnnotatedDeclaredType type) {
    AnnotatedPrimitiveType primitive = super.getUnboxedType(type);
    primitive.replaceAnnotation(INTERNED);
    return primitive;
  }
}
