package org.checkerframework.framework.test;

import java.io.File;
import java.util.List;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.signature.qual.BinaryName;

/** A configuration for running CheckerFrameworkTests or running the TypecheckExecutor. */
public interface TestConfiguration {
  /**
   * Returns a list of source files a CheckerFrameworkPerDirectoryTest should be run over. These
   * source files will be passed to Javac when the test is run. These are NOT JUnit tests.
   *
   * @return a list of source files a CheckerFrameworkPerDirectoryTest should be run over
   */
  List<File> getTestSourceFiles();

  /**
   * Diagnostic files consist of a set of lines that enumerate expected error/warning diagnostics.
   * The lines are of the form:
   *
   * <pre>fileName:lineNumber: diagnostKind: (messageKey)</pre>
   *
   * e.g.,
   *
   * <pre>MethodInvocation.java:17: error: (method.invocation)</pre>
   *
   * If getDiagnosticFiles does NOT return an empty list, then the only diagnostics expected by the
   * TestExecutor will be the ones found in these files. If it does return an empty list, then the
   * only diagnostics expected will be the ones found in comments in the input test files.
   *
   * <p>It is preferred that users write the errors in the test files and not in diagnostic files.
   *
   * @return a List of diagnostic files containing the error/warning messages expected to be output
   *     when Javac is run on the files returned by getTestSourceFiles. Return an empty list if
   *     these messages were specified within the source files.
   */
  List<File> getDiagnosticFiles();

  /**
   * Returns a list of annotation processors (Checkers) passed to the Javac compiler.
   *
   * @return a list of annotation processors (Checkers) passed to the Javac compiler
   */
  List<@BinaryName String> getProcessors();

  /**
   * Some Javac command line arguments require arguments themselves (e.g. {@code -classpath} takes a
   * path) getOptions returns a {@code Map(optionName => optionArgumentIfAny)}. If an option does
   * not take an argument, pass null as the value.
   *
   * <p>E.g.,
   *
   * <pre>{@code
   * Map(
   *   "-AprintAllQualifiers" => null
   *    "-classpath" => "myDir1:myDir2"
   * )
   * }</pre>
   *
   * @return a Map representing all command-line options to Javac other than source files and
   *     processors
   */
  Map<String, @Nullable String> getOptions();

  /**
   * Returns the map returned by {@link #getOptions}, flattened into a list. The entries will be
   * added as followed: List(key1, value1, key2, value2, ..., keyN, valueN). If a value is NULL,
   * then it will not appear in the list.
   *
   * @return the map returned {@link #getOptions}, but flattened into a list
   */
  List<String> getFlatOptions();

  /**
   * Returns true if the TypecheckExecutor should emit debug information on system out, false
   * otherwise.
   *
   * @return true if the TypecheckExecutor should emit debug information on system out, false
   *     otherwise
   */
  boolean shouldEmitDebugInfo();
}
