// Copyright 2017 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.genrule;

import static com.google.common.collect.ImmutableMap.toImmutableMap;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLines;
import com.google.devtools.build.lib.actions.CompositeRunfilesSupplier;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.analysis.AliasProvider;
import com.google.devtools.build.lib.analysis.CommandConstructor;
import com.google.devtools.build.lib.analysis.CommandHelper;
import com.google.devtools.build.lib.analysis.ConfigurationMakeVariableContext;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.MakeVariableSupplier;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.ShToolchain;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.stringtemplate.ExpansionException;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec;
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.AttributeMap;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.util.OnDemandString;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * A base implementation of genrule, to be used by specific implementing rules which can change some
 * of the semantics around when the execution info and inputs are changed.
 */
public abstract class GenRuleBase implements RuleConfiguredTargetFactory {

  /**
   * Returns {@code true} if the rule should be stamped.
   *
   * <p>Genrule implementations can set this based on the rule context, including by defining their
   * own attributes over and above what is present in {@link GenRuleBaseRule}.
   */
  protected abstract boolean isStampingEnabled(RuleContext ruleContext);

  /** Collects sources from src attribute. */
  protected ImmutableMap<Label, NestedSet<Artifact>> collectSources(
      List<? extends TransitiveInfoCollection> srcs) throws RuleErrorException {
    ImmutableMap.Builder<Label, NestedSet<Artifact>> labelMap = ImmutableMap.builder();

    for (TransitiveInfoCollection dep : srcs) {
      NestedSet<Artifact> files = dep.getProvider(FileProvider.class).getFilesToBuild();
      labelMap.put(AliasProvider.getDependencyLabel(dep), files);
    }

    return labelMap.build();
  }

  enum CommandType {
    BASH,
    WINDOWS_BATCH,
    WINDOWS_POWERSHELL,
  }

  @Nullable
  private static Pair<CommandType, String> determineCommandTypeAndAttribute(
      RuleContext ruleContext) {
    AttributeMap attributeMap = ruleContext.attributes();
    // TODO(pcloudy): This should match the execution platform instead of using OS.getCurrent()
    if (OS.getCurrent() == OS.WINDOWS) {
      if (attributeMap.isAttributeValueExplicitlySpecified("cmd_ps")) {
        return Pair.of(CommandType.WINDOWS_POWERSHELL, "cmd_ps");
      }
      if (attributeMap.isAttributeValueExplicitlySpecified("cmd_bat")) {
        return Pair.of(CommandType.WINDOWS_BATCH, "cmd_bat");
      }
    }
    if (attributeMap.isAttributeValueExplicitlySpecified("cmd_bash")) {
      return Pair.of(CommandType.BASH, "cmd_bash");
    }
    if (attributeMap.isAttributeValueExplicitlySpecified("cmd")) {
      return Pair.of(CommandType.BASH, "cmd");
    }
    ruleContext.attributeError(
        "cmd",
        "missing value for `cmd` attribute, you can also set `cmd_ps` or `cmd_bat` on"
            + " Windows and `cmd_bash` on other platforms.");
    return null;
  }

  @Override
  @Nullable
  public ConfiguredTarget create(RuleContext ruleContext)
      throws InterruptedException, RuleErrorException, ActionConflictException {
    NestedSet<Artifact> filesToBuild =
        NestedSetBuilder.wrap(Order.STABLE_ORDER, ruleContext.getOutputArtifacts());

    if (filesToBuild.isEmpty()) {
      ruleContext.attributeError("outs", "Genrules without outputs don't make sense");
    }
    if (ruleContext.attributes().get("executable", Type.BOOLEAN)
        && !filesToBuild.isEmpty()
        && !filesToBuild.isSingleton()) {
      ruleContext.attributeError(
          "executable",
          "if genrules produce executables, they are allowed only one output. "
              + "If you need the executable=1 argument, then you should split this genrule into "
              + "genrules producing single outputs");
    }

    Pair<CommandType, String> cmdTypeAndAttr = determineCommandTypeAndAttribute(ruleContext);

    ImmutableMap<Label, NestedSet<Artifact>> labelMap =
        collectSources(ruleContext.getPrerequisites("srcs"));
    NestedSetBuilder<Artifact> resolvedSrcsBuilder = NestedSetBuilder.stableOrder();
    labelMap.values().forEach(resolvedSrcsBuilder::addTransitive);
    NestedSet<Artifact> resolvedSrcs = resolvedSrcsBuilder.build();

    // The CommandHelper class makes an explicit copy of this in the constructor, so flattening
    // here should be benign.
    CommandHelper commandHelper =
        commandHelperBuilder(ruleContext)
            .addLabelMap(
                labelMap.entrySet().stream()
                    .collect(toImmutableMap(Map.Entry::getKey, e -> e.getValue().toList())))
            .build();

    if (ruleContext.hasErrors()) {
      return null;
    }

    CommandType cmdType = cmdTypeAndAttr.first;
    String cmdAttr = cmdTypeAndAttr.second;
    boolean expandToWindowsPath = cmdType == CommandType.WINDOWS_BATCH;

    String baseCommand = ruleContext.attributes().get(cmdAttr, Type.STRING);

    // Expand template variables and functions.
    CommandResolverContext commandResolverContext =
        new CommandResolverContext(
            ruleContext,
            resolvedSrcs,
            filesToBuild,
            /* makeVariableSuppliers = */ ImmutableList.of(),
            expandToWindowsPath);
    String command =
        ruleContext
            .getExpander(commandResolverContext)
            .withExecLocationsNoSrcs(commandHelper.getLabelMap(), expandToWindowsPath)
            .expand(cmdAttr, baseCommand);

    // Heuristically expand things that look like labels.
    if (ruleContext.attributes().get("heuristic_label_expansion", Type.BOOLEAN)) {
      command = commandHelper.expandLabelsHeuristically(command);
    }

    if (cmdType == CommandType.BASH) {
      // Add the genrule environment setup script before the actual shell command.
      command =
          String.format(
              "source %s; %s",
              ruleContext.getPrerequisiteArtifact("$genrule_setup").getExecPath(), command);
    }

    String messageAttr = ruleContext.attributes().get("message", Type.STRING);
    String message = messageAttr.isEmpty() ? "Executing genrule" : messageAttr;
    Label label = ruleContext.getLabel();
    OnDemandString progressMessage =
        new OnDemandString() {
          @Override
          public String toString() {
            return message + " " + label;
          }
        };

    Map<String, String> executionInfo = Maps.newLinkedHashMap();
    executionInfo.putAll(TargetUtils.getExecutionInfo(ruleContext.getRule()));

    if (ruleContext.attributes().get("local", Type.BOOLEAN)) {
      executionInfo.put("local", "");
    }

    ruleContext.getConfiguration().modifyExecutionInfo(executionInfo, GenRuleAction.MNEMONIC);

    NestedSetBuilder<Artifact> inputs = NestedSetBuilder.stableOrder();
    inputs.addTransitive(resolvedSrcs);
    inputs.addTransitive(commandHelper.getResolvedTools());
    if (cmdType == CommandType.BASH) {
      FilesToRunProvider genruleSetup =
          ruleContext.getPrerequisite("$genrule_setup", FilesToRunProvider.class);
      inputs.addTransitive(genruleSetup.getFilesToRun());
    }
    if (ruleContext.hasErrors()) {
      return null;
    }

    CommandConstructor constructor;
    switch (cmdType) {
      case WINDOWS_BATCH:
        constructor = CommandHelper.buildWindowsBatchCommandConstructor(".genrule_script.bat");
        break;
      case WINDOWS_POWERSHELL:
        constructor = CommandHelper.buildWindowsPowershellCommandConstructor(".genrule_script.ps1");
        break;
      case BASH:
      default:
        // TODO(b/234923262): Take exec_group into consideration when selecting sh tools
        PathFragment shExecutable =
            ShToolchain.getPathForPlatform(
                ruleContext.getConfiguration(), ruleContext.getExecutionPlatform());
        constructor =
            CommandHelper.buildBashCommandConstructor(
                executionInfo, shExecutable, ".genrule_script.sh");
    }
    List<String> argv = commandHelper.buildCommandLine(command, inputs, constructor);

    if (isStampingEnabled(ruleContext)) {
      inputs.add(ruleContext.getAnalysisEnvironment().getStableWorkspaceStatusArtifact());
      inputs.add(ruleContext.getAnalysisEnvironment().getVolatileWorkspaceStatusArtifact());
    }

    ruleContext.registerAction(
        new GenRuleAction(
            ruleContext.getActionOwner(),
            commandHelper.getResolvedTools(),
            inputs.build(),
            filesToBuild.toSet(),
            CommandLines.of(argv),
            ruleContext.getConfiguration().getActionEnvironment(),
            ImmutableMap.copyOf(executionInfo),
            CompositeRunfilesSupplier.fromSuppliers(commandHelper.getToolsRunfilesSuppliers()),
            progressMessage));

    RunfilesProvider runfilesProvider =
        RunfilesProvider.withData(
            // No runfiles provided if not a data dependency.
            Runfiles.EMPTY,
            // We only need to consider the outputs of a genrule. No need to visit the dependencies
            // of a genrule. They cross from the target into the exec configuration, because the
            // dependencies of a genrule are always built for the exec configuration.
            new Runfiles.Builder(
                    ruleContext.getWorkspaceName(),
                    ruleContext.getConfiguration().legacyExternalRunfiles())
                .addTransitiveArtifacts(filesToBuild)
                .build());

    return new RuleConfiguredTargetBuilder(ruleContext)
        .setFilesToBuild(filesToBuild)
        .setRunfilesSupport(null, getExecutable(ruleContext, filesToBuild))
        .addProvider(RunfilesProvider.class, runfilesProvider)
        .addNativeDeclaredProvider(
            InstrumentedFilesCollector.collect(
                ruleContext,
                new InstrumentationSpec(FileTypeSet.ANY_FILE).withSourceAttributes("srcs")))
        .build();
  }

  protected CommandHelper.Builder commandHelperBuilder(RuleContext ruleContext) {
    return CommandHelper.builder(ruleContext)
        .addToolDependencies("tools")
        .addToolDependencies("exec_tools")
        .addToolDependencies("toolchains");
  }

  /**
   * Returns the executable artifact, if the rule is marked as executable and there is only one
   * artifact.
   */
  @Nullable
  private static Artifact getExecutable(RuleContext ruleContext, NestedSet<Artifact> filesToBuild) {
    if (!ruleContext.attributes().get("executable", Type.BOOLEAN)) {
      return null;
    }
    return filesToBuild.isSingleton() ? filesToBuild.getSingleton() : null;
  }

  /**
   * Implementation of {@link ConfigurationMakeVariableContext} used to expand variables in a
   * genrule command string.
   */
  protected static class CommandResolverContext extends ConfigurationMakeVariableContext {

    private final RuleContext ruleContext;
    private final NestedSet<Artifact> resolvedSrcs;
    private final NestedSet<Artifact> filesToBuild;
    private final boolean windowsPath;

    public CommandResolverContext(
        RuleContext ruleContext,
        NestedSet<Artifact> resolvedSrcs,
        NestedSet<Artifact> filesToBuild,
        Iterable<? extends MakeVariableSupplier> makeVariableSuppliers,
        boolean windowsPath) {
      super(
          ruleContext,
          ruleContext.getRule().getPackage(),
          ruleContext.getConfiguration(),
          makeVariableSuppliers);
      this.ruleContext = ruleContext;
      this.resolvedSrcs = resolvedSrcs;
      this.filesToBuild = filesToBuild;
      this.windowsPath = windowsPath;
    }

    public RuleContext getRuleContext() {
      return ruleContext;
    }

    @Override
    public String lookupVariable(String variableName) throws ExpansionException {
      String val = lookupVariableImpl(variableName);
      if (windowsPath) {
        return val.replace('/', '\\');
      }
      return val;
    }

    private String lookupVariableImpl(String variableName) throws ExpansionException {
      if (variableName.equals("SRCS")) {
        return Artifact.joinExecPaths(" ", resolvedSrcs.toList());
      }

      if (variableName.equals("<")) {
        return expandSingletonArtifact(resolvedSrcs, "$<", "input file");
      }

      if (variableName.equals("OUTS")) {
        return Artifact.joinExecPaths(" ", filesToBuild.toList());
      }

      if (variableName.equals("@")) {
        return expandSingletonArtifact(filesToBuild, "$@", "output file");
      }

      PathFragment ruleDirPackagePath = ruleContext.getPackageDirectory();
      PathFragment ruleDirExecPath =
          ruleContext.getBinOrGenfilesDirectory().getExecPath().getRelative(ruleDirPackagePath);

      if (variableName.equals("RULEDIR")) {
        // The output root directory. This variable expands to the package's root directory
        // in the genfiles tree.
        return ruleDirExecPath.getPathString();
      }

      if (variableName.equals("@D")) {
        // The output directory. If there is only one filename in outs,
        // this expands to the directory containing that file. If there are
        // multiple filenames, this variable instead expands to the
        // package's root directory in the genfiles tree, even if all the
        // generated files belong to the same subdirectory!
        if (filesToBuild.isSingleton()) {
          Artifact outputFile = filesToBuild.getSingleton();
          PathFragment relativeOutputFile = outputFile.getExecPath();
          if (!relativeOutputFile.isMultiSegment()) {
            // This should never happen, since the path should contain at
            // least a package name and a file name.
            throw new IllegalStateException(
                "$(@D) for genrule " + ruleContext.getLabel() + " has less than one segment");
          }
          return relativeOutputFile.getParentDirectory().getPathString();
        } else {
          return ruleDirExecPath.getPathString();
        }
      }

      return super.lookupVariable(variableName);
    }

    /**
     * Returns the path of the sole element "artifacts", generating an exception with an informative
     * error message iff the set is not a singleton. Used to expand "$<", "$@".
     */
    private static final String expandSingletonArtifact(
        NestedSet<Artifact> artifacts, String variable, String artifactName)
        throws ExpansionException {
      if (artifacts.isEmpty()) {
        throw new ExpansionException("variable '" + variable
            + "' : no " + artifactName);
      } else if (!artifacts.isSingleton()) {
        throw new ExpansionException("variable '" + variable
            + "' : more than one " + artifactName);
      }
      return artifacts.getSingleton().getExecPathString();
    }
  }
}
