// Copyright 2014 The Bazel Authors. All rights reserved.
//
// 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
//
//    http://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 com.google.devtools.build.buildjar;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.MoreFiles;
import com.google.devtools.build.buildjar.instrumentation.JacocoInstrumentationProcessor;
import com.google.devtools.build.buildjar.javac.BlazeJavacArguments;
import com.google.devtools.build.buildjar.javac.JavacOptions;
import com.google.devtools.build.buildjar.javac.JavacOptions.FilteredJavacopts;
import com.google.devtools.build.buildjar.javac.plugins.BlazeJavaCompilerPlugin;
import com.google.devtools.build.buildjar.javac.plugins.dependency.DependencyModule;
import com.google.devtools.build.buildjar.javac.plugins.processing.AnnotationProcessingModule;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.OptionalInt;
import javax.annotation.Nullable;

/** All the information needed to perform a single Java library build operation. */
public final class JavaLibraryBuildRequest {
  private ImmutableList<String> javacOpts;

  /** Where to store source files generated by annotation processors. */
  private final Path sourceGenDir;

  /** The path to an output jar for source files generated by annotation processors. */
  private final Path generatedSourcesOutputJar;

  /** The path to an output jar for classfiles generated by annotation processors. */
  private final Path generatedClassOutputJar;

  private final ArrayList<Path> sourceFiles;
  private final ImmutableList<Path> sourceJars;

  private final ImmutableList<Path> sourcePath;
  private final ImmutableList<Path> classPath;
  private final ImmutableList<Path> bootClassPath;
  private final Path system;

  private final ImmutableList<Path> processorPath;
  private final List<String> processorNames;
  private final ImmutableSet<String> builtinProcessorNames;

  private final Path outputJar;
  private final Path nativeHeaderOutput;
  @Nullable private final String targetLabel;
  @Nullable private final String injectingRuleKind;

  private final Path classDir;
  private final Path tempDir;

  private JacocoInstrumentationProcessor jacocoInstrumentationProcessor;

  private final boolean compressJar;

  private final OptionsParser.ReduceClasspathMode reduceClasspathMode;
  private final int fullClasspathLength;
  private final int reducedClasspathLength;

  /** Repository for all dependency-related information. */
  private final DependencyModule dependencyModule;

  /** Repository for information about annotation processor-generated symbols. */
  private final AnnotationProcessingModule processingModule;

  /** List of plugins that are given to javac. */
  private final ImmutableList<BlazeJavaCompilerPlugin> plugins;

  /** Map of inputs' path and digest */
  private final ImmutableMap<String, ByteString> inputsAndDigest;

  private final OptionalInt requestId;

  /**
   * Constructs a build from a list of command args. Sets the same JavacRunner for both compilation
   * and annotation processing.
   *
   * @param optionsParser the parsed command line args.
   * @param extraPlugins extraneous plugins to use in addition to the strict dependency module.
   * @throws InvalidCommandLineException on any command line error
   */
  public JavaLibraryBuildRequest(
      OptionsParser optionsParser, List<BlazeJavaCompilerPlugin> extraPlugins)
      throws InvalidCommandLineException, IOException {
    this(optionsParser, extraPlugins, new DependencyModule.Builder());
  }

  /**
   * Constructs a build from a list of command args. Sets the same JavacRunner for both compilation
   * and annotation processing.
   *
   * @param optionsParser the parsed command line args.
   * @param extraPlugins extraneous plugins to use in addition to the strict dependency module.
   * @param depsBuilder a preconstructed dependency module builder.
   * @throws InvalidCommandLineException on any command line error
   */
  public JavaLibraryBuildRequest(
      OptionsParser optionsParser,
      List<BlazeJavaCompilerPlugin> extraPlugins,
      DependencyModule.Builder depsBuilder)
      throws InvalidCommandLineException, IOException {
    this(optionsParser, extraPlugins, depsBuilder, ImmutableMap.of(), OptionalInt.empty());
  }

  /**
   * Constructs a build from a list of command args. Sets the same JavacRunner for both compilation
   * and annotation processing.
   *
   * @param optionsParser the parsed command line args.
   * @param extraPlugins extraneous plugins to use in addition to the strict dependency module.
   * @param depsBuilder a preconstructed dependency module builder.
   * @param inputsAndDigest a map of inputs' paths and their digest
   * @throws InvalidCommandLineException on any command line error
   */
  public JavaLibraryBuildRequest(
      OptionsParser optionsParser,
      List<BlazeJavaCompilerPlugin> extraPlugins,
      DependencyModule.Builder depsBuilder,
      ImmutableMap<String, ByteString> inputsAndDigest,
      OptionalInt requestId)
      throws InvalidCommandLineException, IOException {
    depsBuilder.setDirectJars(
        optionsParser.directJars().stream().map(Paths::get).collect(toImmutableSet()));
    if (optionsParser.getStrictJavaDeps() != null) {
      depsBuilder.setStrictJavaDeps(optionsParser.getStrictJavaDeps());
    }
    if (optionsParser.getOutputDepsProtoFile() != null) {
      depsBuilder.setOutputDepsProtoFile(Paths.get(optionsParser.getOutputDepsProtoFile()));
    }
    depsBuilder.addDepsArtifacts(asPaths(optionsParser.getDepsArtifacts()));
    depsBuilder.setPlatformJars(
        optionsParser.getBootClassPath().stream().map(Paths::get).collect(toImmutableSet()));
    if (optionsParser.reduceClasspathMode() != OptionsParser.ReduceClasspathMode.NONE) {
      depsBuilder.setReduceClasspath();
    }
    if (optionsParser.getTargetLabel() != null) {
      depsBuilder.setTargetLabel(optionsParser.getTargetLabel());
    }
    this.dependencyModule = depsBuilder.build();
    this.sourceGenDir =
        deriveDirectory(optionsParser.getTargetLabel(), optionsParser.getOutputJar(), "_sources");

    AnnotationProcessingModule.Builder processingBuilder = AnnotationProcessingModule.builder();
    processingBuilder.setSourceGenDir(sourceGenDir);
    if (optionsParser.getManifestProtoPath() != null) {
      processingBuilder.setManifestProtoPath(Paths.get(optionsParser.getManifestProtoPath()));
    }
    this.processingModule = processingBuilder.build();

    ImmutableList.Builder<BlazeJavaCompilerPlugin> pluginsBuilder =
        ImmutableList.<BlazeJavaCompilerPlugin>builder().add(dependencyModule.getPlugin());
    processingModule.registerPlugin(pluginsBuilder);
    pluginsBuilder.addAll(extraPlugins);
    this.plugins = pluginsBuilder.build();

    this.compressJar = optionsParser.compressJar();
    this.reduceClasspathMode = optionsParser.reduceClasspathMode();
    this.fullClasspathLength = optionsParser.fullClasspathLength();
    this.reducedClasspathLength = optionsParser.reducedClasspathLength();
    this.sourceFiles = new ArrayList<>(asPaths(optionsParser.getSourceFiles()));
    this.sourceJars = asPaths(optionsParser.getSourceJars());
    this.classPath = asPaths(optionsParser.getClassPath());
    this.sourcePath = asPaths(optionsParser.getSourcePath());
    this.bootClassPath = asPaths(optionsParser.getBootClassPath());
    this.system = asPath(optionsParser.getSystem());
    this.processorPath = asPaths(optionsParser.getProcessorPath());
    this.processorNames = optionsParser.getProcessorNames();
    this.builtinProcessorNames = ImmutableSet.copyOf(optionsParser.getBuiltinProcessorNames());
    this.classDir =
        deriveDirectory(optionsParser.getTargetLabel(), optionsParser.getOutputJar(), "_classes");
    this.tempDir =
        deriveDirectory(optionsParser.getTargetLabel(), optionsParser.getOutputJar(), "_tmp");
    this.outputJar = asPath(optionsParser.getOutputJar());
    this.nativeHeaderOutput = asPath(optionsParser.getNativeHeaderOutput());
    for (Map.Entry<String, List<String>> entry : optionsParser.getPostProcessors().entrySet()) {
      switch (entry.getKey()) {
        case "jacoco":
          this.jacocoInstrumentationProcessor =
              JacocoInstrumentationProcessor.create(entry.getValue());
          break;
        default:
          throw new AssertionError("unsupported post-processor " + entry.getKey());
      }
    }
    this.javacOpts = ImmutableList.copyOf(optionsParser.getJavacOpts());
    this.generatedSourcesOutputJar = asPath(optionsParser.getGeneratedSourcesOutputJar());
    this.generatedClassOutputJar = asPath(optionsParser.getManifestProtoPath());
    this.targetLabel = optionsParser.getTargetLabel();
    this.injectingRuleKind = optionsParser.getInjectingRuleKind();
    this.inputsAndDigest = inputsAndDigest;
    this.requestId = requestId;
  }

  /**
   * Derive a temporary directory path based on the path to the output jar, to avoid breaking
   * fragile assumptions made by the implementation of javahotswap.
   */
  // TODO(b/169793789): kill this with fire if javahotswap starts using jars instead of classes
  @VisibleForTesting
  static Path deriveDirectory(String label, String outputJar, String suffix) throws IOException {
    checkArgument(label != null, "--target_label is required");
    checkArgument(outputJar != null, "--output is required");
    checkArgument(
        label.contains(":"), "--target_label must be a canonical label (containing a `:`)");

    Path path = Paths.get(outputJar);
    String name = MoreFiles.getNameWithoutExtension(path);
    String base = label.substring(label.lastIndexOf(':') + 1);
    return path.resolveSibling("_javac").resolve(base).resolve(name + suffix);
  }

  private static ImmutableList<Path> asPaths(Collection<String> paths) {
    return paths.stream().map(Paths::get).collect(toImmutableList());
  }

  @Nullable
  private static Path asPath(@Nullable String path) {
    return path != null ? Paths.get(path) : null;
  }

  public ImmutableList<String> getJavacOpts() {
    return javacOpts;
  }

  public Path getSourceGenDir() {
    return sourceGenDir;
  }

  public ImmutableList<Path> getSourcePath() {
    return sourcePath;
  }

  public Path getGeneratedSourcesOutputJar() {
    return generatedSourcesOutputJar;
  }

  public Path getGeneratedClassOutputJar() {
    return generatedClassOutputJar;
  }

  public ArrayList<Path> getSourceFiles() {
    // TODO(cushon): This is being modified after parsing to add files from source jars.
    return sourceFiles;
  }

  public ImmutableList<Path> getSourceJars() {
    return sourceJars;
  }

  public ImmutableList<Path> getClassPath() {
    return classPath;
  }

  public ImmutableList<Path> getBootClassPath() {
    return bootClassPath;
  }

  public Path getSystem() {
    return system;
  }

  public ImmutableList<Path> getProcessorPath() {
    return processorPath;
  }

  public List<String> getProcessors() {
    // TODO(bazel-team): This might be modified by a JavaLibraryBuilder to enable specific
    // annotation processors.
    return processorNames;
  }

  public Path getOutputJar() {
    return outputJar;
  }

  public Path getNativeHeaderOutput() {
    return nativeHeaderOutput;
  }

  public Path getClassDir() {
    return classDir;
  }

  public Path getTempDir() {
    return tempDir;
  }

  public Path getNativeHeaderDir() {
    return getTempDir().resolve("native_headers");
  }

  public JacocoInstrumentationProcessor getJacocoInstrumentationProcessor() {
    return jacocoInstrumentationProcessor;
  }

  public boolean compressJar() {
    return compressJar;
  }

  public OptionsParser.ReduceClasspathMode reduceClasspathMode() {
    return reduceClasspathMode;
  }

  public int fullClasspathLength() {
    return fullClasspathLength;
  }

  public int reducedClasspathLength() {
    return reducedClasspathLength;
  }

  public DependencyModule getDependencyModule() {
    return dependencyModule;
  }

  public AnnotationProcessingModule getProcessingModule() {
    return processingModule;
  }

  public ImmutableList<BlazeJavaCompilerPlugin> getPlugins() {
    return plugins;
  }

  public ImmutableMap<String, ByteString> getInputsAndDigest() {
    return inputsAndDigest;
  }

  public OptionalInt getRequestId() {
    return requestId;
  }

  @Nullable
  public String getTargetLabel() {
    return targetLabel;
  }

  @Nullable
  public String getInjectingRuleKind() {
    return injectingRuleKind;
  }

  public BlazeJavacArguments toBlazeJavacArguments(ImmutableList<Path> classPath) {
    BlazeJavacArguments.Builder builder =
        BlazeJavacArguments.builder()
            .classPath(classPath)
            .classOutput(getClassDir())
            .bootClassPath(getBootClassPath())
            .system(getSystem())
            .sourceFiles(ImmutableList.copyOf(getSourceFiles()))
            .builtinProcessors(builtinProcessorNames)
            .sourcePath(getSourcePath())
            .sourceOutput(getSourceGenDir())
            .processorPath(getProcessorPath())
            .plugins(getPlugins())
            .inputsAndDigest(getInputsAndDigest())
            .requestId(getRequestId());
    addJavacArguments(builder);
    // Performance optimization: when reduced classpaths are enabled, stop the compilation after
    // the first diagnostic that would result in fallback to the transitive classpath. The user
    // only sees diagnostics from the fallback compilation, so collecting additional diagnostics
    // from the reduced classpath compilation is a waste of time.
    // Exception: this doesn't hold if annotation processing is enabled, since diagnostics may be
    // resolved during subsequent processing rounds.
    if (reduceClasspathMode.equals(OptionsParser.ReduceClasspathMode.BAZEL_REDUCED)
        && getProcessors().isEmpty()) {
      builder.failFast(getProcessors().isEmpty());
    }
    if (getNativeHeaderOutput() != null) {
      builder.nativeHeaderOutput(getNativeHeaderDir());
    }
    return builder.build();
  }

  /** Constructs a command line that can be used for a javac invocation. */
  void addJavacArguments(BlazeJavacArguments.Builder builder) {
    FilteredJavacopts filtered = JavacOptions.filterJavacopts(getJavacOpts());
    builder.blazeJavacOptions(filtered.bazelJavacopts());

    ImmutableList<String> javacOpts = filtered.standardJavacopts();

    ImmutableList.Builder<String> javacArguments = ImmutableList.builder();

    // default to -implicit:none, but allow the user to override with -implicit:class.
    javacArguments.add("-implicit:none");
    javacArguments.addAll(javacOpts);

    if (!getProcessors().isEmpty() && !getSourceFiles().isEmpty()) {
      // ImmutableSet.copyOf maintains order
      ImmutableSet<String> deduplicatedProcessorNames = ImmutableSet.copyOf(getProcessors());
      javacArguments.add("-processor");
      javacArguments.add(Joiner.on(',').join(deduplicatedProcessorNames));
    } else {
      // This is necessary because some jars contain discoverable annotation processors that
      // previously didn't run, and they break builds if the "-proc:none" option is not passed to
      // javac.
      javacArguments.add("-proc:none");
    }

    for (String option : javacOpts) {
      if (option.startsWith("-J")) { // ignore the VM options.
        continue;
      }
      if (option.equals("-processor") || option.equals("-processorpath")) {
        throw new IllegalStateException(
            "Using "
                + option
                + " in javacopts is no longer supported."
                + " Use a java_plugin() rule instead.");
      }
    }

    builder.javacOptions(javacArguments.build());
  }
}
