package org.checkerframework.common.util.count;

import com.sun.source.tree.AnnotationTree;
import com.sun.source.tree.ArrayAccessTree;
import com.sun.source.tree.AssertTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.NewArrayTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.ParameterizedTypeTree;
import com.sun.source.tree.TypeCastTree;
import com.sun.tools.javac.util.Log;
import java.util.List;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.ExecutableElement;
import org.checkerframework.framework.source.SourceChecker;
import org.checkerframework.framework.source.SourceVisitor;
import org.checkerframework.javacutil.AnnotationProvider;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.TreeUtils;

/**
 * An annotation processor for counting the size of Java code:
 *
 * <ul>
 *   <li>The number of type parameter declarations and uses.
 *   <li>The number of array accesses and dimensions in array creations.
 *   <li>The number of type casts.
 * </ul>
 *
 * <p>To invoke it, use
 *
 * <pre>
 * javac -proc:only -processor org.checkerframework.common.util.count.JavaCodeStatistics <em>MyFile.java ...</em>
 * </pre>
 *
 * @see AnnotationStatistics
 */
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class JavaCodeStatistics extends SourceChecker {

  /** The number of type parameter declarations and uses. */
  int generics = 0;
  /** The number of array accesses and dimensions in array creations. */
  int arrayAccesses = 0;
  /** The number of type casts. */
  int typecasts = 0;

  String[] warningKeys = {
    "index", "lowerbound", "samelen", "searchindex", "substringindex", "upperbound"
  };
  /**
   * The number of warning suppressions with at least one key that matches one of the Index Checker
   * subcheckers.
   */
  int numberOfIndexWarningSuppressions = 0;

  /** The SuppressWarnings.value field/element. */
  final ExecutableElement suppressWarningsValueElement =
      TreeUtils.getMethod(SuppressWarnings.class, "value", 0, processingEnv);

  /** Creates a JavaCodeStatistics. */
  public JavaCodeStatistics() {
    // This checker never issues any warnings, so don't warn about
    // @SuppressWarnings("allcheckers:...").
    this.useAllcheckersPrefix = false;
  }

  @Override
  public void typeProcessingOver() {
    Log log = getCompilerLog();
    if (log.nerrors != 0) {
      System.out.printf("Not outputting statistics, because compilation issued an error.%n");
    } else {
      System.out.printf("Found %d generic type uses.%n", generics);
      System.out.printf("Found %d array accesses and creations.%n", arrayAccesses);
      System.out.printf("Found %d typecasts.%n", typecasts);
      System.out.printf(
          "Found %d warning suppression annotations for the Index Checker.%n",
          numberOfIndexWarningSuppressions);
    }
    super.typeProcessingOver();
  }

  @Override
  protected SourceVisitor<?, ?> createSourceVisitor() {
    return new Visitor(this);
  }

  class Visitor extends SourceVisitor<Void, Void> {

    public Visitor(JavaCodeStatistics l) {
      super(l);
    }

    @Override
    public Void visitAnnotation(AnnotationTree node, Void aVoid) {
      AnnotationMirror annotationMirror = TreeUtils.annotationFromAnnotationTree(node);
      if (AnnotationUtils.annotationName(annotationMirror)
          .equals(SuppressWarnings.class.getCanonicalName())) {
        List<String> keys =
            AnnotationUtils.getElementValueArray(
                annotationMirror, suppressWarningsValueElement, String.class);
        for (String foundKey : keys) {
          for (String indexKey : warningKeys) {
            if (foundKey.startsWith(indexKey)) {
              numberOfIndexWarningSuppressions++;
              return super.visitAnnotation(node, aVoid);
            }
          }
        }
      }
      return super.visitAnnotation(node, aVoid);
    }

    @Override
    public Void visitAssert(AssertTree tree, Void aVoid) {
      ExpressionTree detail = tree.getDetail();
      if (detail != null) {
        String msg = detail.toString();
        for (String indexKey : warningKeys) {
          String key = "@AssumeAssertion(" + indexKey;
          if (msg.contains(key)) {
            numberOfIndexWarningSuppressions++;
            return super.visitAssert(tree, aVoid);
          }
        }
      }
      return super.visitAssert(tree, aVoid);
    }

    @Override
    public Void visitClass(ClassTree tree, Void p) {
      if (shouldSkipDefs(tree)) {
        // Not "return super.visitClass(classTree, p);" because that would recursively call visitors
        // on subtrees; we want to skip the class entirely.
        return null;
      }
      generics += tree.getTypeParameters().size();
      return super.visitClass(tree, p);
    }

    @Override
    public Void visitNewArray(NewArrayTree node, Void aVoid) {
      arrayAccesses += node.getDimensions().size();

      return super.visitNewArray(node, aVoid);
    }

    @Override
    public Void visitNewClass(NewClassTree node, Void aVoid) {
      if (TreeUtils.isDiamondTree(node)) {
        generics++;
      }
      generics += node.getTypeArguments().size();
      return super.visitNewClass(node, aVoid);
    }

    @Override
    public Void visitMethodInvocation(MethodInvocationTree node, Void aVoid) {
      generics += node.getTypeArguments().size();
      return super.visitMethodInvocation(node, aVoid);
    }

    @Override
    public Void visitMethod(MethodTree node, Void aVoid) {
      generics += node.getTypeParameters().size();
      return super.visitMethod(node, aVoid);
    }

    @Override
    public Void visitParameterizedType(ParameterizedTypeTree tree, Void p) {
      generics += tree.getTypeArguments().size();
      return super.visitParameterizedType(tree, p);
    }

    @Override
    public Void visitArrayAccess(ArrayAccessTree node, Void aVoid) {
      arrayAccesses++;
      return super.visitArrayAccess(node, aVoid);
    }

    @Override
    public Void visitTypeCast(TypeCastTree node, Void aVoid) {
      typecasts++;
      return super.visitTypeCast(node, aVoid);
    }
  }

  @Override
  public AnnotationProvider getAnnotationProvider() {
    throw new UnsupportedOperationException(
        "getAnnotationProvider is not implemented for this class.");
  }
}
