// 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.TransitionMode;
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.rules.java.JavaConfiguration.ImportDepsCheckingLevel;
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 ImportDepsCheckActionBuilder() {}

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

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

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

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

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

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

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

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

    ruleContext.registerAction(
        new SpawnAction.Builder()
            .useDefaultShellEnvironment()
            .setExecutable(
                ruleContext.getExecutablePrerequisite("$import_deps_checker", TransitionMode.HOST))
            .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);
    }
  }
}
