// Note that "-processor org/checkerframework/checker.nullness.NullnessChecker"
// is added to the invocation of the compiler!
// TODO: add a @Processor method-annotation to parameterize

/**
 * This class has auxiliary methods to compile a class and return its classfile. It is used by
 * defaultPersists/Driver and inheritDeclAnnoPersist/Driver.
 */
import com.sun.tools.classfile.ClassFile;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.StringJoiner;

public class PersistUtil {

  public static String testClassOf(Method m) {
    TestClass tc = m.getAnnotation(TestClass.class);
    if (tc != null) {
      return tc.value();
    } else {
      return "Test";
    }
  }

  public static ClassFile compileAndReturn(String fullFile, String testClass) throws Exception {
    File source = writeTestFile(fullFile);
    File clazzFile = compileTestFile(source, testClass);
    return ClassFile.read(clazzFile);
  }

  public static File writeTestFile(String fullFile) throws IOException {
    File f = new File("Test.java");
    PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
    out.println(fullFile);
    out.close();
    return f;
  }

  public static File compileTestFile(File f, String testClass) {
    int rc =
        com.sun.tools.javac.Main.compile(
            new String[] {
              "-source",
              "1.8",
              "-g",
              "-processor",
              "org.checkerframework.checker.nullness.NullnessChecker",
              f.getPath()
            });
    if (rc != 0) {
      throw new Error("compilation failed. rc=" + rc);
    }
    String path;
    if (f.getParent() != null) {
      path = f.getParent();
    } else {
      path = "";
    }

    return new File(path + testClass + ".class");
  }

  public static String wrap(String compact) {
    StringJoiner sj = new StringJoiner(System.lineSeparator());

    // Automatically import java.util
    sj.add("");
    sj.add("import java.util.*;");
    sj.add("import java.lang.annotation.*;");

    // And the Nullness qualifiers
    sj.add("import org.checkerframework.framework.qual.DefaultQualifier;");
    sj.add("import org.checkerframework.checker.nullness.qual.*;");
    sj.add("import org.checkerframework.dataflow.qual.*;");

    sj.add("");
    boolean isSnippet =
        !(compact.startsWith("class") || compact.contains(" class"))
            && !compact.contains("interface")
            && !compact.contains("enum");

    if (isSnippet) {
      sj.add("class Test {");
    }

    sj.add(compact);

    if (isSnippet) {
      sj.add("}");
      sj.add("");
    }

    return sj.toString();
  }
}

/**
 * The name of the class that should be analyzed. Should only need to be provided when analyzing
 * inner classes.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface TestClass {
  String value() default "Test";
}
