// Copyright 2018 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.lib.rules.java;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.java.JavaConfiguration.ImportDepsCheckingLevel;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.stream.Collectors;

/** Utility for generating a call to the import_deps_checker. */
public final class ImportDepsCheckActionBuilder {

  public static ImportDepsCheckActionBuilder newBuilder() {
    return new ImportDepsCheckActionBuilder();
  }

  private Artifact jdepsArtifact;
  private Label ruleLabel;
  private NestedSet<Artifact> jarsToCheck;
  private NestedSet<Artifact> bootclasspath;
  private NestedSet<Artifact> declaredDeps;
  private NestedSet<Artifact> transitiveDeps;
  private ImportDepsCheckingLevel importDepsCheckingLevel;
  private Artifact importDepsChecker;

  private ImportDepsCheckActionBuilder() {}

  @CanIgnoreReturnValue
  public ImportDepsCheckActionBuilder checkJars(NestedSet<Artifact> jarsToCheck) {
    checkState(this.jarsToCheck == null);
    this.jarsToCheck = checkNotNull(jarsToCheck);
    return this;
  }

  @CanIgnoreReturnValue
  public ImportDepsCheckActionBuilder ruleLabel(Label ruleLabel) {
    checkState(this.ruleLabel == null);
    this.ruleLabel = checkNotNull(ruleLabel);
    return this;
  }

  @CanIgnoreReturnValue
  public ImportDepsCheckActionBuilder importDepsCheckingLevel(
      ImportDepsCheckingLevel importDepsCheckingLevel) {
    checkState(this.importDepsCheckingLevel == null);
    this.importDepsCheckingLevel = checkNotNull(importDepsCheckingLevel);
    return this;
  }

  @CanIgnoreReturnValue
  public ImportDepsCheckActionBuilder bootclasspath(NestedSet<Artifact> bootclasspath) {
    checkState(this.bootclasspath == null);
    this.bootclasspath = checkNotNull(bootclasspath);
    return this;
  }

  @CanIgnoreReturnValue
  public ImportDepsCheckActionBuilder jdepsOutputArtifact(Artifact jdepsArtifact) {
    checkState(this.jdepsArtifact == null);
    this.jdepsArtifact = checkNotNull(jdepsArtifact);
    return this;
  }

  @CanIgnoreReturnValue
  public ImportDepsCheckActionBuilder declareDeps(NestedSet<Artifact> declaredDeps) {
    checkState(this.declaredDeps == null);
    this.declaredDeps = checkNotNull(declaredDeps);
    return this;
  }

  @CanIgnoreReturnValue
  public ImportDepsCheckActionBuilder transitiveDeps(NestedSet<Artifact> transitiveDeps) {
    checkState(this.transitiveDeps == null);
    this.transitiveDeps = checkNotNull(transitiveDeps);
    return this;
  }

  public void buildAndRegister(RuleContext ruleContext) throws RuleErrorException {
    checkNotNull(jarsToCheck);
    checkNotNull(bootclasspath);
    checkNotNull(declaredDeps);
    checkNotNull(transitiveDeps);
    checkNotNull(importDepsCheckingLevel);
    checkNotNull(jdepsArtifact);
    checkNotNull(ruleLabel);

    SpawnAction.Builder builder = new SpawnAction.Builder();
    if (importDepsChecker == null) {
      builder.setExecutable(ruleContext.getExecutablePrerequisite("$import_deps_checker"));
    } else {
      builder
          .addTransitiveInputs(JavaRuntimeInfo.forHost(ruleContext).javaBaseInputs())
          .setJarExecutable(
              JavaCommon.getHostJavaExecutable(ruleContext),
              importDepsChecker,
              NestedSetBuilder.emptySet(Order.STABLE_ORDER));
    }
    ruleContext.registerAction(
        builder
            .useDefaultShellEnvironment()
            .addTransitiveInputs(jarsToCheck)
            .addTransitiveInputs(declaredDeps)
            .addTransitiveInputs(transitiveDeps)
            .addTransitiveInputs(bootclasspath)
            .addOutput(jdepsArtifact)
            .setMnemonic("ImportDepsChecker")
            .setProgressMessage(
                "Checking the completeness of the deps for %s",
                jarsToCheck.toList().stream()
                    .map(Artifact::prettyPrint)
                    .collect(Collectors.joining(", ")))
            .addCommandLine(buildCommandLine())
            .build(ruleContext));
  }

  private CustomCommandLine buildCommandLine() {
    return CustomCommandLine.builder()
        .addExecPaths(VectorArg.addBefore("--input").each(jarsToCheck))
        .addExecPaths(VectorArg.addBefore("--directdep").each(declaredDeps))
        .addExecPaths(VectorArg.addBefore("--classpath_entry").each(transitiveDeps))
        .addExecPaths(VectorArg.addBefore("--bootclasspath_entry").each(bootclasspath))
        .addDynamicString(convertErrorFlag(importDepsCheckingLevel))
        .addExecPath("--jdeps_output", jdepsArtifact)
        .add("--rule_label", ruleLabel.toString())
        .build();
  }

  private static String convertErrorFlag(ImportDepsCheckingLevel level) {
    switch (level) {
      case ERROR:
        return "--checking_mode=error";
      case WARNING:
        return "--checking_mode=warning";
      case OFF:
        return "--checking_mode=silence";
      default:
        throw new RuntimeException("Unhandled deps checking level: " + level);
    }
  }
}
