package org.checkerframework.framework.test;

import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import org.checkerframework.framework.test.diagnostics.JavaDiagnosticReader;
import org.checkerframework.framework.test.diagnostics.TestDiagnostic;
import org.checkerframework.javacutil.SystemUtil;
import org.plumelib.util.StringsPlume;

/** Used by the Checker Framework test suite to run the framework and generate a test result. */
public class TypecheckExecutor {

  /** Creates a new TypecheckExecutor. */
  public TypecheckExecutor() {}

  /**
   * Runs a typechecking test using the given configuration and returns the test result.
   *
   * @param configuration the test configuration
   * @return the test result
   */
  public TypecheckResult runTest(TestConfiguration configuration) {
    try {
      CompilationResult result = compile(configuration);
      return interpretResults(configuration, result);
    } catch (OutOfMemoryError e) {
      String message =
          String.format(
              "Max memory = %d, total memory = %d, free memory = %d.",
              Runtime.getRuntime().maxMemory(),
              Runtime.getRuntime().totalMemory(),
              Runtime.getRuntime().freeMemory());
      System.out.println(message);
      System.err.println(message);
      throw new Error(message, e);
    }
  }

  /**
   * Using the settings from the input configuration, compile all source files in the configuration,
   * and return the result in a CompilationResult.
   */
  public CompilationResult compile(TestConfiguration configuration) {
    String dOption = configuration.getOptions().get("-d");
    if (dOption == null) {
      throw new Error("-d not supplied");
    }
    TestUtilities.ensureDirectoryExists(dOption);

    final StringWriter javacOutput = new StringWriter();
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    Iterable<? extends JavaFileObject> javaFiles =
        fileManager.getJavaFileObjects(configuration.getTestSourceFiles().toArray(new File[] {}));

    // Even though the method compiler.getTask takes a list of processors, it fails if
    // processors are passed this way with the message:
    //   error: Class names, 'org.checkerframework.checker.interning.InterningChecker', are only
    //   accepted if annotation processing is explicitly requested
    // Therefore, we now add them to the beginning of the options list.
    final List<String> options = new ArrayList<>();
    options.add("-processor");
    options.add(String.join(",", configuration.getProcessors()));
    if (SystemUtil.getJreVersion() == 8) {
      options.add("-source");
      options.add("8");
      options.add("-target");
      options.add("8");
    }

    List<String> nonJvmOptions = new ArrayList<>();
    for (String option : configuration.getFlatOptions()) {
      if (!option.startsWith("-J-")) {
        nonJvmOptions.add(option);
      }
    }
    nonJvmOptions.add("-Xmaxerrs");
    nonJvmOptions.add("100000");
    nonJvmOptions.add("-Xmaxwarns");
    nonJvmOptions.add("100000");
    nonJvmOptions.add("-Xlint:deprecation");

    nonJvmOptions.add("-ApermitMissingJdk");
    nonJvmOptions.add("-Anocheckjdk"); // temporary, for backward compatibility

    options.addAll(nonJvmOptions);

    if (configuration.shouldEmitDebugInfo()) {
      System.out.println("Running test using the following invocation:");
      System.out.println(
          "javac "
              + String.join(" ", options)
              + " "
              + StringsPlume.join(" ", configuration.getTestSourceFiles()));
    }

    JavaCompiler.CompilationTask task =
        compiler.getTask(
            javacOutput, fileManager, diagnostics, options, new ArrayList<String>(), javaFiles);

    /*
     * In Eclipse, std out and std err for multiple tests appear as one
     * long stream. When selecting a specific failed test, one sees the
     * expected/unexpected messages, but not the std out/err messages from
     * that particular test. Can we improve this somehow?
     */
    final Boolean compiledWithoutError = task.call();
    javacOutput.flush();
    return new CompilationResult(
        compiledWithoutError, javacOutput.toString(), javaFiles, diagnostics.getDiagnostics());
  }

  /**
   * Reads the expected diagnostics for the given configuration and creates a TypecheckResult which
   * contains all of the missing and expected diagnostics.
   */
  public TypecheckResult interpretResults(
      TestConfiguration config, CompilationResult compilationResult) {
    List<TestDiagnostic> expectedDiagnostics = readDiagnostics(config, compilationResult);
    return TypecheckResult.fromCompilationResults(config, compilationResult, expectedDiagnostics);
  }

  /**
   * A subclass can override this to filter out errors or add new expected errors. This method is
   * called immediately before results are checked.
   */
  protected List<TestDiagnostic> readDiagnostics(
      TestConfiguration config, CompilationResult compilationResult) {
    List<TestDiagnostic> expectedDiagnostics;
    if (config.getDiagnosticFiles() == null || config.getDiagnosticFiles().isEmpty()) {
      expectedDiagnostics =
          JavaDiagnosticReader.readJavaSourceFiles(compilationResult.getJavaFileObjects());
    } else {
      expectedDiagnostics = JavaDiagnosticReader.readDiagnosticFiles(config.getDiagnosticFiles());
    }

    return expectedDiagnostics;
  }
}
