// Copyright 2016 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.cpp;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.AbstractAction;
import com.google.devtools.build.lib.actions.ActionEnvironment;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ActionExecutionException;
import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.CommandLines;
import com.google.devtools.build.lib.actions.CommandLines.CommandLineLimits;
import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.actions.RunfilesSupplier;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * Action used by LtoBackendArtifacts to create an LtoBackendAction. Similar to {@link SpawnAction},
 * except that inputs are discovered from the imports file created by the ThinLTO indexing step for
 * each backend artifact.
 *
 * <p>See {@link LtoBackendArtifacts} for a high level description of the ThinLTO build process. The
 * LTO indexing step takes all bitcode .o files and decides which other .o file symbols can be
 * imported/inlined. The additional input files for each backend action are then written to an
 * imports file. Therefore these new inputs must be discovered here by subsetting the imports paths
 * from the set of all bitcode artifacts, before executing the backend action.
 *
 * <p>For more information on ThinLTO see
 * http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html.
 */
public final class LtoBackendAction extends SpawnAction {
  private Collection<Artifact> mandatoryInputs;
  private Map<PathFragment, Artifact> bitcodeFiles;
  private Artifact imports;

  private static final String GUID = "72ce1eca-4625-4e24-a0d8-bb91bb8b0e0e";

  public LtoBackendAction(
      Collection<Artifact> inputs,
      Map<PathFragment, Artifact> allBitcodeFiles,
      Artifact importsFile,
      Collection<Artifact> outputs,
      Artifact primaryOutput,
      ActionOwner owner,
      CommandLines argv,
      CommandLineLimits commandLineLimits,
      boolean isShellCommand,
      ActionEnvironment env,
      Map<String, String> executionInfo,
      CharSequence progressMessage,
      RunfilesSupplier runfilesSupplier,
      String mnemonic) {
    super(
        owner,
        ImmutableList.<Artifact>of(),
        inputs,
        outputs,
        primaryOutput,
        AbstractAction.DEFAULT_RESOURCE_SET,
        argv,
        commandLineLimits,
        isShellCommand,
        env,
        ImmutableMap.copyOf(executionInfo),
        progressMessage,
        runfilesSupplier,
        mnemonic,
        false,
        null);
    mandatoryInputs = inputs;
    Preconditions.checkState(
        (bitcodeFiles == null) == (imports == null),
        "Either both or neither bitcodeFiles and imports files should be null");
    bitcodeFiles = allBitcodeFiles;
    imports = importsFile;
  }

  @Override
  public boolean discoversInputs() {
    return imports != null;
  }

  private Set<Artifact> computeBitcodeInputs(Collection<PathFragment> inputPaths) {
    HashSet<Artifact> bitcodeInputs = new HashSet<>();
    for (PathFragment inputPath : inputPaths) {
      Artifact inputArtifact = bitcodeFiles.get(inputPath);
      if (inputArtifact != null) {
        bitcodeInputs.add(inputArtifact);
      }
    }
    return bitcodeInputs;
  }

  @Nullable
  @Override
  public Iterable<Artifact> discoverInputs(ActionExecutionContext actionExecutionContext)
      throws ActionExecutionException, InterruptedException {
    // Build set of files this LTO backend artifact will import from.
    HashSet<PathFragment> importSet = new HashSet<>();
    try {
      for (String line :
          FileSystemUtils.iterateLinesAsLatin1(actionExecutionContext.getInputPath(imports))) {
        if (!line.isEmpty()) {
          PathFragment execPath = PathFragment.create(line);
          if (execPath.isAbsolute()) {
            throw new ActionExecutionException(
                "Absolute paths not allowed in imports file "
                    + actionExecutionContext.getInputPath(imports)
                    + ": "
                    + execPath,
                this,
                false);
          }
          importSet.add(PathFragment.create(line));
        }
      }
    } catch (IOException e) {
      throw new ActionExecutionException(
          "error iterating imports file " + actionExecutionContext.getInputPath(imports),
          e,
          this,
          false);
    }

    // Convert the import set of paths to the set of bitcode file artifacts.
    Set<Artifact> bitcodeInputSet = computeBitcodeInputs(importSet);
    if (bitcodeInputSet.size() != importSet.size()) {
      throw new ActionExecutionException(
          "error computing inputs from imports file "
              + actionExecutionContext.getInputPath(imports),
          this,
          false);
    }
    updateInputs(createInputs(bitcodeInputSet, getMandatoryInputs()));
    return bitcodeInputSet;
  }

  @Override
  public Collection<Artifact> getMandatoryInputs() {
    return mandatoryInputs;
  }

  private static Iterable<Artifact> createInputs(
      Set<Artifact> newInputs, Collection<Artifact> curInputs) {
    Set<Artifact> result = new LinkedHashSet<>(newInputs);
    result.addAll(curInputs);
    return result;
  }

  @Override
  public Iterable<Artifact> getAllowedDerivedInputs() {
    return bitcodeFiles.values();
  }

  @Override
  protected void computeKey(ActionKeyContext actionKeyContext, Fingerprint fp) {
    fp.addString(GUID);
    try {
      fp.addStrings(getArguments());
    } catch (CommandLineExpansionException e) {
      throw new AssertionError("LtoBackendAction command line expansion cannot fail");
    }
    fp.addString(getMnemonic());
    fp.addPaths(getRunfilesSupplier().getRunfilesDirs());
    ImmutableList<Artifact> runfilesManifests = getRunfilesSupplier().getManifests();
    for (Artifact runfilesManifest : runfilesManifests) {
      fp.addPath(runfilesManifest.getExecPath());
    }
    for (Artifact input : getMandatoryInputs()) {
      fp.addPath(input.getExecPath());
    }
    if (imports != null) {
      for (PathFragment bitcodePath : bitcodeFiles.keySet()) {
        fp.addPath(bitcodePath);
      }
      fp.addPath(imports.getExecPath());
    }
    env.addTo(fp);
    fp.addStringMap(getExecutionInfo());
  }

  /** Builder class to construct {@link LtoBackendAction} instances. */
  public static class Builder extends SpawnAction.Builder {
    private Map<PathFragment, Artifact> bitcodeFiles;
    private Artifact imports;

    public Builder addImportsInfo(
        Map<PathFragment, Artifact> allBitcodeFiles, Artifact importsFile) {
      this.bitcodeFiles = allBitcodeFiles;
      this.imports = importsFile;
      return this;
    }

    @Override
    protected SpawnAction createSpawnAction(
        ActionOwner owner,
        NestedSet<Artifact> tools,
        NestedSet<Artifact> inputsAndTools,
        ImmutableList<Artifact> outputs,
        Artifact primaryOutput,
        ResourceSet resourceSet,
        CommandLines commandLines,
        CommandLineLimits commandLineLimits,
        boolean isShellCommand,
        ActionEnvironment env,
        ImmutableMap<String, String> executionInfo,
        CharSequence progressMessage,
        RunfilesSupplier runfilesSupplier,
        String mnemonic) {
      return new LtoBackendAction(
          inputsAndTools.toCollection(),
          bitcodeFiles,
          imports,
          outputs,
          primaryOutput,
          owner,
          commandLines,
          commandLineLimits,
          isShellCommand,
          env,
          executionInfo,
          progressMessage,
          runfilesSupplier,
          mnemonic);
    }
  }
}
