package org.checkerframework.framework.testchecker.util;

import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.Tree;
import com.sun.tools.javac.tree.JCTree;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.processing.SupportedOptions;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.tools.JavaFileObject;
import org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.common.basetype.BaseTypeVisitor;
import org.checkerframework.framework.source.SourceChecker;
import org.checkerframework.framework.type.GenericAnnotatedTypeFactory;
import org.checkerframework.javacutil.BugInCF;
import org.checkerframework.javacutil.TreeUtils;

/**
 * A specialized checker for testing purposes. It compares an expression's annotated type to an
 * expected type.
 *
 * <p>The expected type is written in a stylized comment (starting with "///") in the same Java
 * source file. The comment appears either on the same line as the expression, or else by itself on
 * the line preceding the expression.
 *
 * <p>The comments are of two forms:
 *
 * <ul>
 *   <li>{@code /// <expected type>}: to specify the type of the expression in the expression
 *       statement
 *   <li>{@code /// <subtree> -:- <expected type>}: to specify the type of the given subexpression
 *       within the line.
 * </ul>
 *
 * The specified types are allowed to use simple names (e.g., {@code List<String>}), instead of
 * fully qualified names (e.g., {@code java.util.List<java.lang.String>}).
 *
 * <p>Example:
 *
 * <pre>
 *  void test() {
 *      // Comments in the same line
 *      Collections.<@NonNull String>emptyList();  /// List<@NonNull String>
 *      List<@NonNull String> l = Collections.emptyList(); /// Collections.emptyList() -:- List<@NonNull String>
 *
 *      // Comments in the previous lines
 *      /// List<@NonNull String>
 *      Collections.<@NonNull String>emptyList();
 *
 *      /// Collections.emptyList() -:- List<@NonNull String>
 *      List<@NonNull String> l = Collections.emptyList();
 *  }
 * </pre>
 *
 * The fully qualified name of the custom <i>AnnotatedTypeFactory</i> is specified through an {@code
 * -Afactory} command-line argument (e.g. {@code
 * -Afactory=checkers.nullness.NullnessAnnotatedTypeFactory}). The factory needs to have a
 * constructor of the form {@code <init>(ProcessingEnvironment, CompilationUnitTree)}.
 */
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedOptions({"checker"})
public class FactoryTestChecker extends BaseTypeChecker {
  SourceChecker checker;

  @Override
  public void initChecker() {
    super.initChecker();

    // Find factory constructor
    String checkerClassName = getOption("checker");
    try {
      if (checkerClassName != null) {
        Class<?> checkerClass = Class.forName(checkerClassName);
        Constructor<?> constructor = checkerClass.getConstructor();
        Object o = constructor.newInstance();
        if (o instanceof SourceChecker) {
          checker = (SourceChecker) o;
        }
      }
    } catch (Exception e) {
      throw new BugInCF("Couldn't load " + checkerClassName + " class.");
    }
  }

  /*
  @Override
  public AnnotatedTypeFactory createTypeFactory() {
      return checker.createTypeFactory();
  }*/

  @Override
  public Properties getMessagesProperties() {
    // We don't have any properties
    Properties prop = new Properties();
    prop.setProperty(
        "type.unexpected",
        "unexpected type for the given tree%n"
            + "Tree       : %s%n"
            + "Found      : %s%n"
            + "Expected   : %s%n");
    return prop;
  }

  @Override
  protected BaseTypeVisitor<?> createSourceVisitor() {
    return new ToStringVisitor(this);
  }

  /** Builds the expected type for the trees from the source file of the tree compilation unit. */
  // This method is extremely ugly
  private Map<TreeSpec, String> buildExpected(CompilationUnitTree tree) {
    Map<TreeSpec, String> expected = new HashMap<>();
    try {
      JavaFileObject o = tree.getSourceFile();
      File sourceFile = new File(o.toUri());
      LineNumberReader reader = new LineNumberReader(new FileReader(sourceFile));
      String line = reader.readLine();
      Pattern prevsubtreePattern = Pattern.compile("\\s*///(.*)-:-(.*)");
      Pattern prevfulltreePattern = Pattern.compile("\\s*///(.*)");
      Pattern subtreePattern = Pattern.compile("(.*)///(.*)-:-(.*)");
      Pattern fulltreePattern = Pattern.compile("(.*)///(.*)");
      while (line != null) {
        Matcher prevsubtreeMatcher = prevsubtreePattern.matcher(line);
        Matcher prevfulltreeMatcher = prevfulltreePattern.matcher(line);
        Matcher subtreeMatcher = subtreePattern.matcher(line);
        Matcher fulltreeMatcher = fulltreePattern.matcher(line);
        if (prevsubtreeMatcher.matches()) {
          String treeString = prevsubtreeMatcher.group(1).trim();
          if (treeString.endsWith(";")) {
            treeString = treeString.substring(0, treeString.length() - 1);
          }
          TreeSpec treeSpec = new TreeSpec(treeString.trim(), reader.getLineNumber() + 1);
          expected.put(treeSpec, canonizeTypeString(prevsubtreeMatcher.group(2)));
        } else if (prevfulltreeMatcher.matches()) {
          String treeString = reader.readLine().trim();
          if (treeString.endsWith(";")) {
            treeString = treeString.substring(0, treeString.length() - 1);
          }
          TreeSpec treeSpec = new TreeSpec(treeString.trim(), reader.getLineNumber());
          expected.put(treeSpec, canonizeTypeString(prevfulltreeMatcher.group(1)));
        } else if (subtreeMatcher.matches()) {
          String treeString = subtreeMatcher.group(2).trim();
          if (treeString.endsWith(";")) {
            treeString = treeString.substring(0, treeString.length() - 1);
          }
          TreeSpec treeSpec = new TreeSpec(treeString.trim(), reader.getLineNumber());
          expected.put(treeSpec, canonizeTypeString(subtreeMatcher.group(3)));
        } else if (fulltreeMatcher.matches()) {
          String treeString = fulltreeMatcher.group(1).trim();
          if (treeString.endsWith(";")) {
            treeString = treeString.substring(0, treeString.length() - 1);
          }
          TreeSpec treeSpec = new TreeSpec(treeString.trim(), reader.getLineNumber());
          expected.put(treeSpec, canonizeTypeString(fulltreeMatcher.group(2)));
        }
        line = reader.readLine();
      }
      reader.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return expected;
  }

  /** A method to canonize the tree representation. */
  private static String canonizeTreeString(String str) {
    String canon = str.trim();
    Pattern pattern = Pattern.compile("(@\\S+)\\(\\)");
    Matcher matcher = pattern.matcher(canon);
    while (matcher.find()) {
      canon = matcher.replaceFirst(matcher.group(1));
      matcher.reset(canon);
    }
    return canon.trim();
  }

  /**
   * A method to canonize type string representation. It removes any unnecessary white spaces and
   * finds the type simple name instead of the fully qualified name.
   *
   * @param str the type string representation
   * @return a canonical representation of the type
   */
  private static String canonizeTypeString(String str) {
    String canon = str.trim();
    canon = canon.replaceAll("\\s+", " ");
    // Remove spaces between [ ]
    canon = canon.replaceAll("\\[\\s+", "[");
    canon = canon.replaceAll("\\s+\\]", "]");

    // Remove spaces between < >
    canon = canon.replaceAll("<\\s+", "<");
    canon = canon.replaceAll("\\s+>", ">");

    // Take simply names!
    canon = canon.replaceAll("[^\\<]*\\.(?=\\w)", "");
    return canon;
  }

  /**
   * A data structure that encapsulate a string and the line number that string appears in the
   * buffer
   */
  private static class TreeSpec {
    public final String treeString;
    public final long lineNumber;

    public TreeSpec(String treeString, long lineNumber) {
      this.treeString = canonizeTreeString(treeString);
      this.lineNumber = lineNumber;
    }

    @Override
    public int hashCode() {
      return Objects.hash(treeString, lineNumber);
    }

    @Override
    public boolean equals(Object o) {
      if (o instanceof TreeSpec) {
        TreeSpec other = (TreeSpec) o;
        return treeString.equals(other.treeString) && lineNumber == other.lineNumber;
      }
      return false;
    }

    @Override
    public String toString() {
      return lineNumber + ":" + treeString;
    }
  }

  /**
   * A specialized visitor that compares the actual and expected types for the specified trees and
   * report an error if they differ
   */
  private class ToStringVisitor extends BaseTypeVisitor<GenericAnnotatedTypeFactory<?, ?, ?, ?>> {
    Map<TreeSpec, String> expected;

    public ToStringVisitor(BaseTypeChecker checker) {
      super(checker);
      this.expected = buildExpected(root);
    }

    @Override
    public Void scan(Tree tree, Void p) {
      if (TreeUtils.isExpressionTree(tree)) {
        ExpressionTree expTree = (ExpressionTree) tree;
        TreeSpec treeSpec =
            new TreeSpec(
                expTree.toString().trim(), root.getLineMap().getLineNumber(((JCTree) expTree).pos));
        if (expected.containsKey(treeSpec)) {
          String actualType = canonizeTypeString(atypeFactory.getAnnotatedType(expTree).toString());
          String expectedType = expected.get(treeSpec);
          if (!actualType.equals(expectedType)) {

            // The key is added above using a setProperty call, which is not supported
            // by the CompilerMessagesChecker.
            @SuppressWarnings("compilermessages")
            @CompilerMessageKey String key = "type.unexpected";
            FactoryTestChecker.this.reportError(
                tree, key, tree.toString(), actualType, expectedType);
          }
        }
      }
      return super.scan(tree, p);
    }
  }
}
