// 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.lib.rules.cpp;

import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.util.stream.Collectors.joining;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.flogger.GoogleLogger;
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.ActionOwner;
import com.google.devtools.build.lib.actions.ActionResult;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.actions.Spawn;
import com.google.devtools.build.lib.actions.SpawnResult;
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.concurrent.ThreadSafety.ThreadCompatible;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.exec.SpawnStrategyResolver;
import com.google.devtools.build.lib.packages.StarlarkSemanticsOptions;
import com.google.devtools.build.lib.rules.cpp.CcCommon.CoptsFilter;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.util.ShellEscaper;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
 * Action that represents a fake C++ compilation step.
 */
@ThreadCompatible
public class FakeCppCompileAction extends CppCompileAction {

  private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();

  public static final UUID GUID = UUID.fromString("8ab63589-be01-4a39-b770-b98ae8b03493");

  private final PathFragment tempOutputFile;

  FakeCppCompileAction(
      ActionOwner owner,
      FeatureConfiguration featureConfiguration,
      CcToolchainVariables variables,
      Artifact sourceFile,
      CppConfiguration cppConfiguration,
      boolean shareable,
      boolean shouldScanIncludes,
      boolean shouldPruneModules,
      boolean usePic,
      boolean useHeaderModules,
      NestedSet<Artifact> mandatoryInputs,
      NestedSet<Artifact> inputsForInvalidation,
      ImmutableList<Artifact> builtinIncludeFiles,
      NestedSet<Artifact> prunableHeaders,
      Artifact outputFile,
      PathFragment tempOutputFile,
      Artifact dotdFile,
      ActionEnvironment env,
      CcCompilationContext ccCompilationContext,
      CoptsFilter nocopts,
      CppSemantics cppSemantics,
      ImmutableList<PathFragment> builtInIncludeDirectories,
      ImmutableMap<String, String> executionInfo,
      Artifact grepIncludes) {
    super(
        owner,
        featureConfiguration,
        variables,
        sourceFile,
        cppConfiguration,
        shareable,
        shouldScanIncludes,
        shouldPruneModules,
        usePic,
        useHeaderModules,
        mandatoryInputs,
        inputsForInvalidation,
        builtinIncludeFiles,
        prunableHeaders,
        outputFile,
        dotdFile,
        /* gcnoFile=*/ null,
        /* dwoFile=*/ null,
        /* ltoIndexingFile=*/ null,
        env,
        // We only allow inclusion of header files explicitly declared in
        // "srcs", so we only use declaredIncludeSrcs, not declaredIncludeDirs.
        // (Disallowing use of undeclared headers for cc_fake_binary is needed
        // because the header files get included in the runfiles for the
        // cc_fake_binary and for the negative compilation tests that depend on
        // the cc_fake_binary, and the runfiles must be determined at analysis
        // time, so they can't depend on the contents of the ".d" file.)
        CcCompilationContext.disallowUndeclaredHeaders(ccCompilationContext),
        nocopts,
        /* additionalIncludeScanningRoots=*/ ImmutableList.of(),
        GUID,
        executionInfo,
        CppActionNames.CPP_COMPILE,
        cppSemantics,
        builtInIncludeDirectories,
        grepIncludes);
    this.tempOutputFile = Preconditions.checkNotNull(tempOutputFile);
  }

  @Override
  @ThreadCompatible
  public ActionResult execute(ActionExecutionContext actionExecutionContext)
      throws ActionExecutionException, InterruptedException {
    List<SpawnResult> spawnResults;
    // First, do a normal compilation, to generate the ".d" file. The generated object file is built
    // to a temporary location (tempOutputFile) and ignored afterwards.
    logger.atInfo().log("Generating %s", getDotdFile());
    byte[] dotDContents = null;
    try {
      Spawn spawn = createSpawn(actionExecutionContext.getClientEnv());
      SpawnStrategyResolver spawnStrategyResolver =
          actionExecutionContext.getContext(SpawnStrategyResolver.class);
      spawnResults = spawnStrategyResolver.exec(spawn, actionExecutionContext);
      // The SpawnActionContext guarantees that the first list entry is the successful one.
      dotDContents = getDotDContents(spawnResults.get(0));
    } catch (ExecException e) {
      Label label = getOwner().getLabel();
      throw e.toActionExecutionException(
          "C++ compilation of rule '" + label + "'",
          actionExecutionContext.showVerboseFailures(label),
          this);
    } finally {
      clearAdditionalInputs();
    }
    CppIncludeExtractionContext scanningContext =
        actionExecutionContext.getContext(CppIncludeExtractionContext.class);
    Path execRoot = actionExecutionContext.getExecRoot();

    NestedSet<Artifact> discoveredInputs;
    if (getDotdFile() == null) {
      discoveredInputs = NestedSetBuilder.<Artifact>stableOrder().build();
    } else {
      HeaderDiscovery.Builder discoveryBuilder =
          new HeaderDiscovery.Builder()
              .setAction(this)
              .setSourceFile(getSourceFile())
              .setDependencies(
                  processDepset(actionExecutionContext, execRoot, dotDContents).getDependencies())
              .setPermittedSystemIncludePrefixes(getPermittedSystemIncludePrefixes(execRoot))
              .setAllowedDerivedInputs(getAllowedDerivedInputs());

      if (needsIncludeValidation) {
        discoveryBuilder.shouldValidateInclusions();
      }

      boolean siblingRepositoryLayout =
          actionExecutionContext
              .getOptions()
              .getOptions(StarlarkSemanticsOptions.class)
              .experimentalSiblingRepositoryLayout;

      discoveredInputs =
          discoveryBuilder
              .build()
              .discoverInputsFromDependencies(
                  execRoot, scanningContext.getArtifactResolver(), siblingRepositoryLayout);
    }

    dotDContents = null; // Garbage collect in-memory .d contents.

    // Even cc_fake_binary rules need to properly declare their dependencies...
    // In fact, they need to declare their dependencies even more than cc_binary rules do.
    // CcCommonConfiguredTarget passes in an empty set of declaredIncludeDirs,
    // so this check below will only allow inclusion of header files that are explicitly
    // listed in the "srcs" of the cc_fake_binary or in the "srcs" of a cc_library that it
    // depends on.
    try {
      validateInclusions(actionExecutionContext, discoveredInputs);
    } catch (ActionExecutionException e) {
      // TODO(bazel-team): (2009) make this into an error, once most of the current warnings
      // are fixed.
      actionExecutionContext
          .getEventHandler()
          .handle(
              Event.warn(
                  getOwner().getLocation(),
                  e.getMessage() + ";\n  this warning may eventually become an error"));
    }

    if (discoversInputs()) {
      updateActionInputs(discoveredInputs);
    } else {
      Preconditions.checkState(
          discoveredInputs.isEmpty(),
          "Discovered inputs without discovering inputs? %s %s",
          discoveredInputs,
          this);
    }

    // Generate a fake ".o" file containing the command line needed to generate
    // the real object file.
    logger.atInfo().log("Generating %s", outputFile);

    // A cc_fake_binary rule generates fake .o files and a fake target file,
    // which merely contain instructions on building the real target. We need to
    // be careful to use a new set of output file names in the instructions, as
    // to not overwrite the fake output files when someone tries to follow the
    // instructions. As the real compilation is executed by the test from its
    // runfiles directory (where writing is forbidden), we patch the command
    // line to write to $TEST_TMPDIR instead.
    final String outputPrefix = "$TEST_TMPDIR/";
    String argv;
    try {
      argv =
          getArguments().stream()
              .map(
                  input -> {
                    String result = ShellEscaper.escapeString(input);
                    // Replace -c <tempOutputFile> so it's -c <outputFile>.
                    if (input.equals(tempOutputFile.getPathString())) {
                      result =
                          outputPrefix + ShellEscaper.escapeString(outputFile.getExecPathString());
                    }
                    if (input.equals(outputFile.getExecPathString())
                        || (getDotdFile() != null
                            && input.equals(getDotdFile().getExecPathString()))) {
                      result = outputPrefix + ShellEscaper.escapeString(input);
                    }
                    return result;
                  })
              .collect(joining(" "));
    } catch (CommandLineExpansionException e) {
      throw new ActionExecutionException(
          "failed to generate compile command for rule '"
              + getOwner().getLabel()
              + ": "
              + e.getMessage(),
          this,
          /* catastrophe= */ false);
    }

    // Write the command needed to build the real .o file to the fake .o file.
    // Generate a command to ensure that the output directory exists; otherwise
    // the compilation would fail.
    try {
      // Ensure that the .d file and .o file are siblings, so that the "mkdir" below works for
      // both.
      Preconditions.checkState(
          getDotdFile() == null
              || outputFile
                  .getExecPath()
                  .getParentDirectory()
                  .equals(getDotdFile().getExecPath().getParentDirectory()));
      FileSystemUtils.writeContent(
          actionExecutionContext.getInputPath(outputFile),
          ISO_8859_1,
          actionExecutionContext.getInputPath(outputFile).getBaseName()
              + ": "
              + "mkdir -p "
              + outputPrefix
              + "$(dirname "
              + outputFile.getExecPath()
              + ")"
              + " && "
              + argv
              + "\n");
    } catch (IOException e) {
      throw new ActionExecutionException("failed to create fake compile command for rule '"
          + getOwner().getLabel() + ": " + e.getMessage(), this, false);
    }
    return ActionResult.create(spawnResults);
  }

  @Override
  public String getMnemonic() {
    return "FakeCppCompile";
  }

  @Override
  public ResourceSet estimateResourceConsumptionLocal() {
    return AbstractAction.DEFAULT_RESOURCE_SET;
  }
}
