/*
 * Bach - Java Shell Builder
 * Copyright (C) 2020 Christian Stein
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.sormuras.bach.call;

import java.lang.module.ModuleDescriptor.Version;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Map;

/** A call to {@code javac}, the Java compiler. */
public /*static*/ class Javac extends GenericSourcesConsumer<Javac> {

  private Version versionOfModulesThatAreBeingCompiled;
  private Collection<String> patternsWhereToFindSourceFiles;
  private Map<String, Collection<Path>> pathsWhereToFindSourceFiles;
  private Map<String, Collection<Path>> pathsWhereToFindMoreAssetsPerModule;
  private Collection<Path> pathsWhereToFindApplicationModules;

  private int compileForVirtualMachineVersion;
  private boolean enablePreviewLanguageFeatures;
  private boolean generateMetadataForMethodParameters;
  private boolean outputMessagesAboutWhatTheCompilerIsDoing;
  private boolean outputSourceLocationsOfDeprecatedUsages;
  private boolean terminateCompilationIfWarningsOccur;

  public Javac() {
    super("javac");
  }

  @Override
  public String toLabel() {
    return "Compile module(s): " + getModules();
  }

  @Override
  protected void addConfiguredArguments(Arguments arguments) {
    super.addConfiguredArguments(arguments);

    var version = getVersionOfModulesThatAreBeingCompiled();
    if (assigned(version)) arguments.add("--module-version", version);

    var patterns = getPatternsWhereToFindSourceFiles();
    if (assigned(patterns)) arguments.add("--module-source-path", joinPaths(patterns));

    var specific = getPathsWhereToFindSourceFiles();
    if (assigned(specific))
      for (var entry : specific.entrySet())
        arguments.add("--module-source-path", entry.getKey() + '=' + join(entry.getValue()));

    var patches = getPathsWhereToFindMoreAssetsPerModule();
    if (assigned(patches))
      for (var patch : patches.entrySet())
        arguments.add("--patch-module", patch.getKey() + '=' + join(patch.getValue()));

    var modulePath = getPathsWhereToFindApplicationModules();
    if (assigned(modulePath)) arguments.add("--module-path", join(modulePath));

    var release = getCompileForVirtualMachineVersion();
    if (assigned(release)) arguments.add("--release", release);

    if (isEnablePreviewLanguageFeatures()) arguments.add("--enable-preview");

    if (isGenerateMetadataForMethodParameters()) arguments.add("-parameters");

    if (isOutputSourceLocationsOfDeprecatedUsages()) arguments.add("-deprecation");

    if (isOutputMessagesAboutWhatTheCompilerIsDoing()) arguments.add("-verbose");

    if (isTerminateCompilationIfWarningsOccur()) arguments.add("-Werror");
  }

  public Version getVersionOfModulesThatAreBeingCompiled() {
    return versionOfModulesThatAreBeingCompiled;
  }

  public Javac setVersionOfModulesThatAreBeingCompiled(
      Version versionOfModulesThatAreBeingCompiled) {
    this.versionOfModulesThatAreBeingCompiled = versionOfModulesThatAreBeingCompiled;
    return this;
  }

  public Collection<String> getPatternsWhereToFindSourceFiles() {
    return patternsWhereToFindSourceFiles;
  }

  public Javac setPatternsWhereToFindSourceFiles(Collection<String> patterns) {
    this.patternsWhereToFindSourceFiles = patterns;
    return this;
  }

  public Map<String, Collection<Path>> getPathsWhereToFindSourceFiles() {
    return pathsWhereToFindSourceFiles;
  }

  public Javac setPathsWhereToFindSourceFiles(Map<String, Collection<Path>> map) {
    this.pathsWhereToFindSourceFiles = map;
    return this;
  }

  public Map<String, Collection<Path>> getPathsWhereToFindMoreAssetsPerModule() {
    return pathsWhereToFindMoreAssetsPerModule;
  }

  public Javac setPathsWhereToFindMoreAssetsPerModule(Map<String, Collection<Path>> map) {
    this.pathsWhereToFindMoreAssetsPerModule = map;
    return this;
  }

  public Collection<Path> getPathsWhereToFindApplicationModules() {
    return pathsWhereToFindApplicationModules;
  }

  public Javac setPathsWhereToFindApplicationModules(
      Collection<Path> pathsWhereToFindApplicationModules) {
    this.pathsWhereToFindApplicationModules = pathsWhereToFindApplicationModules;
    return this;
  }

  public int getCompileForVirtualMachineVersion() {
    return compileForVirtualMachineVersion;
  }

  public Javac setCompileForVirtualMachineVersion(int release) {
    this.compileForVirtualMachineVersion = release;
    return this;
  }

  public boolean isEnablePreviewLanguageFeatures() {
    return enablePreviewLanguageFeatures;
  }

  public Javac setEnablePreviewLanguageFeatures(boolean preview) {
    this.enablePreviewLanguageFeatures = preview;
    return this;
  }

  public boolean isGenerateMetadataForMethodParameters() {
    return generateMetadataForMethodParameters;
  }

  public Javac setGenerateMetadataForMethodParameters(boolean parameters) {
    this.generateMetadataForMethodParameters = parameters;
    return this;
  }

  public boolean isOutputMessagesAboutWhatTheCompilerIsDoing() {
    return outputMessagesAboutWhatTheCompilerIsDoing;
  }

  public Javac setOutputMessagesAboutWhatTheCompilerIsDoing(boolean verbose) {
    this.outputMessagesAboutWhatTheCompilerIsDoing = verbose;
    return this;
  }

  public boolean isOutputSourceLocationsOfDeprecatedUsages() {
    return outputSourceLocationsOfDeprecatedUsages;
  }

  public Javac setOutputSourceLocationsOfDeprecatedUsages(boolean deprecation) {
    this.outputSourceLocationsOfDeprecatedUsages = deprecation;
    return this;
  }

  public boolean isTerminateCompilationIfWarningsOccur() {
    return terminateCompilationIfWarningsOccur;
  }

  public Javac setTerminateCompilationIfWarningsOccur(boolean error) {
    this.terminateCompilationIfWarningsOccur = error;
    return this;
  }
}

@@ -753,26 +753,20 @@
 va.util.
-Collection
+List
 ;%0Aimport
@@ -970,26 +970,20 @@
 private 
-Collection
+List
 %3CString%3E
@@ -1033,34 +1033,28 @@
 Map%3CString, 
-Collection
+List
 %3CPath%3E%3E path
@@ -1096,34 +1096,28 @@
 Map%3CString, 
-Collection
+List
 %3CPath%3E%3E path
@@ -1159,26 +1159,20 @@
 private 
-Collection
+List
 %3CPath%3E p
@@ -3523,26 +3523,20 @@
  public 
-Collection
+List
 %3CString%3E
@@ -3671,26 +3671,20 @@
 ceFiles(
-Collection
+List
 %3CString%3E
@@ -3787,34 +3787,28 @@
 Map%3CString, 
-Collection
+List
 %3CPath%3E%3E getP
@@ -3937,34 +3937,28 @@
 Map%3CString, 
-Collection
+List
 %3CPath%3E%3E map)
@@ -4043,34 +4043,28 @@
 Map%3CString, 
-Collection
+List
 %3CPath%3E%3E getP
@@ -4221,26 +4221,20 @@
 String, 
-Collection
+List
 %3CPath%3E%3E 
@@ -4323,26 +4323,20 @@
  public 
-Collection
+List
 %3CPath%3E g
@@ -4492,18 +4492,12 @@
     
-Collection
+List
 %3CPat

Use type List instead of Collection