package org.checkerframework.framework.test;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.signature.qual.BinaryName;
import org.plumelib.util.StringsPlume;

/**
 * Represents all of the information needed to execute the Javac compiler for a given set of test
 * files.
 */
public class ImmutableTestConfiguration implements TestConfiguration {

  /**
   * Options that should be passed to the compiler. This a {@code Map(optionName =>
   * optionArgumentIfAny)}. E.g.,
   *
   * <pre>{@code
   * Map(
   *   "-AprintAllQualifiers" => null
   *    "-classpath" => "myDir1:myDir2"
   * )
   * }</pre>
   */
  private final Map<String, @Nullable String> options;
  /**
   * These files contain diagnostics that should be returned by Javac. If this list is empty, the
   * diagnostics are instead read from comments in the Java file itself
   */
  private final List<File> diagnosticFiles;

  /**
   * The source files to compile. If the file is expected to emit errors on compilation, the file
   * should contain expected error diagnostics OR should have a companion file with the same
   * path/name but with the extension .out instead of .java if they
   */
  private final List<File> testSourceFiles;

  /** A list of AnnotationProcessors (usually checkers) to pass to the compiler for this test. */
  private final List<@BinaryName String> processors;

  /** The value of system property "emit.test.debug". */
  private final boolean shouldEmitDebugInfo;

  /**
   * Create a new ImmutableTestConfiguration.
   *
   * @param diagnosticFiles files containing diagnostics that should be returned by javac
   * @param testSourceFiles the source files to compile
   * @param processors the annotation processors (usually checkers) to run
   * @param options options that should be passed to the compiler
   * @param shouldEmitDebugInfo the value of system property "emit.test.debug"
   */
  public ImmutableTestConfiguration(
      List<File> diagnosticFiles,
      List<File> testSourceFiles,
      List<@BinaryName String> processors,
      Map<String, @Nullable String> options,
      boolean shouldEmitDebugInfo) {
    this.diagnosticFiles = Collections.unmodifiableList(diagnosticFiles);
    this.testSourceFiles = Collections.unmodifiableList(new ArrayList<>(testSourceFiles));
    this.processors = new ArrayList<>(processors);
    this.options =
        Collections.unmodifiableMap(new LinkedHashMap<String, @Nullable String>(options));
    this.shouldEmitDebugInfo = shouldEmitDebugInfo;
  }

  @Override
  public List<File> getTestSourceFiles() {
    return testSourceFiles;
  }

  @Override
  public List<File> getDiagnosticFiles() {
    return diagnosticFiles;
  }

  @Override
  public List<@BinaryName String> getProcessors() {
    return processors;
  }

  @Override
  public Map<String, @Nullable String> getOptions() {
    return options;
  }

  @Override
  public List<String> getFlatOptions() {
    return TestUtilities.optionMapToList(options);
  }

  @Override
  public boolean shouldEmitDebugInfo() {
    return shouldEmitDebugInfo;
  }

  @Override
  public String toString() {
    return StringsPlume.joinLines(
        "TestConfigurationBuilder:",
        "testSourceFiles=" + StringsPlume.join(" ", testSourceFiles),
        "processors=" + String.join(", ", processors),
        "options=" + String.join(", ", getFlatOptions()),
        "shouldEmitDebugInfo=" + shouldEmitDebugInfo);
  }
}
