// Copyright 2020 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.bazel.rules.ninja.actions;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
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.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.NinjaMysteryArtifact;
import com.google.devtools.build.lib.actions.ArtifactResolver;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.actions.CommandLines;
import com.google.devtools.build.lib.actions.CommandLines.CommandLineLimits;
import com.google.devtools.build.lib.actions.EnvironmentalExecException;
import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.actions.RunfilesSupplier;
import com.google.devtools.build.lib.actions.SpawnResult;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.bazel.rules.ninja.parser.NinjaTarget;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.StarlarkSemanticsOptions;
import com.google.devtools.build.lib.rules.cpp.CppIncludeExtractionContext;
import com.google.devtools.build.lib.skyframe.TrackSourceDirectoriesFlag;
import com.google.devtools.build.lib.util.DependencySet;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import java.io.IOException;
import java.util.List;
import javax.annotation.Nullable;

/** Generic class for Ninja actions. Corresponds to the {@link NinjaTarget} in the Ninja file. */
public class NinjaAction extends SpawnAction {
  private static final String MNEMONIC = "NinjaGenericAction";

  private final Root sourceRoot;
  @Nullable private final Artifact depFile;
  private final ImmutableMap<PathFragment, Artifact> allowedDerivedInputs;
  private final ArtifactRoot derivedOutputRoot;
  private final NestedSet<Artifact> originalInputs; // This does not include order-only inputs.
  private final NestedSet<Artifact> orderOnlyInputs;

  public NinjaAction(
      ActionOwner owner,
      Root sourceRoot,
      NestedSet<Artifact> tools,
      NestedSet<Artifact> inputs,
      NestedSet<Artifact> orderOnlyInputs,
      List<? extends Artifact> outputs,
      CommandLines commandLines,
      ActionEnvironment env,
      ImmutableMap<String, String> executionInfo,
      CharSequence progressMessage,
      RunfilesSupplier runfilesSupplier,
      boolean executeUnconditionally,
      @Nullable Artifact depFile,
      ArtifactRoot derivedOutputRoot) {
    super(
        /* owner= */ owner,
        /* tools= */ tools,
        /* inputs= */ inputs,
        /* outputs= */ outputs,
        /* primaryOutput= */ Iterables.getFirst(outputs, null),
        /* resourceSet= */ AbstractAction.DEFAULT_RESOURCE_SET,
        /* commandLines= */ commandLines,
        /* commandLineLimits= */ CommandLineLimits.UNLIMITED,
        /* isShellCommand= */ true,
        /* env= */ env,
        /* executionInfo= */ executionInfo,
        /* progressMessage= */ progressMessage,
        /* runfilesSupplier= */ runfilesSupplier,
        /* mnemonic= */ MNEMONIC,
        /* executeUnconditionally= */ executeUnconditionally,
        /* extraActionInfoSupplier= */ null,
        /* resultConsumer= */ null);
    this.sourceRoot = sourceRoot;
    this.depFile = depFile;

    ImmutableMap.Builder<PathFragment, Artifact> allowedDerivedInputsBuilder =
        ImmutableMap.builder();
    for (Artifact input : inputs.toList()) {
      if (!input.isSourceArtifact()) {
        allowedDerivedInputsBuilder.put(input.getExecPath(), input);
      }
    }
    this.allowedDerivedInputs = allowedDerivedInputsBuilder.build();

    this.derivedOutputRoot = derivedOutputRoot;
    this.originalInputs = inputs;
    this.orderOnlyInputs = orderOnlyInputs;
  }

  @Override
  protected void beforeExecute(ActionExecutionContext actionExecutionContext) throws ExecException {
    if (!TrackSourceDirectoriesFlag.trackSourceDirectories()) {
      checkInputsForDirectories(
          actionExecutionContext.getEventHandler(), actionExecutionContext.getMetadataProvider());
    }
  }

  @Override
  protected void afterExecute(
      ActionExecutionContext actionExecutionContext, List<SpawnResult> spawnResults)
      throws EnvironmentalExecException {
    checkOutputsForDirectories(actionExecutionContext);

    if (depFile == null) {
      // The inputs may have been modified during input discovery to include order-only inputs.
      // Restore the original inputs to exclude those order-only inputs, so that order-only inputs
      // do not cause the action to be rerun. This needs to be done when there is no dep file
      // because updateInputsFromDepfile() will recalculate all the dependencies, and even if an
      // input is order-only, it will cause a rebuild if it's listed in the depfile.
      // Note also that this must check if the order-only inputs are empty, because if they are,
      // discoversInputs() will return false, causing updateInputs() to throw an error.
      if (!orderOnlyInputs.isEmpty()) {
        updateInputs(originalInputs);
      }
    } else {
      updateInputsFromDepfile(actionExecutionContext);
    }
  }

  private void updateInputsFromDepfile(ActionExecutionContext actionExecutionContext)
      throws EnvironmentalExecException {

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

    CppIncludeExtractionContext scanningContext =
        actionExecutionContext.getContext(CppIncludeExtractionContext.class);
    ArtifactResolver artifactResolver = scanningContext.getArtifactResolver();
    Path execRoot = actionExecutionContext.getExecRoot();
    try {
      DependencySet depSet =
          new DependencySet(execRoot).read(actionExecutionContext.getInputPath(depFile));
      NestedSetBuilder<Artifact> inputsBuilder = NestedSetBuilder.stableOrder();
      for (Path inputPath : depSet.getDependencies()) {
        PathFragment execRelativePath = null;

        // This branch needed in case the depfile contains an absolute path to a source file.
        if (sourceRoot.contains(inputPath)) {
          execRelativePath = inputPath.asFragment().relativeTo(sourceRoot.asPath().asFragment());
        } else {
          execRelativePath = inputPath.asFragment().relativeTo(execRoot.asFragment());
        }

        Artifact inputArtifact = null;
        if (allowedDerivedInputs.containsKey(execRelativePath)) {
          // Predeclared generated input.
          inputArtifact = allowedDerivedInputs.get(execRelativePath);
        }
        if (inputArtifact == null) {
          RepositoryName repository =
              PackageIdentifier.discoverFromExecPath(
                      execRelativePath, false, siblingRepositoryLayout)
                  .getRepository();
          if (execRelativePath.startsWith(derivedOutputRoot.getExecPath())) {
            // This input is a generated file which was not declared in the original inputs for
            // this action.
            inputArtifact = new NinjaMysteryArtifact(derivedOutputRoot, execRelativePath);
          } else {
            // Source file input.
            inputArtifact = artifactResolver.resolveSourceArtifact(execRelativePath, repository);
          }
        }

        if (inputArtifact == null) {
          throw new EnvironmentalExecException(
              String.format(
                  "depfile-declared dependency '%s' is invalid: it must either be "
                      + "a source input, or a pre-declared generated input",
                  execRelativePath));
        }

        inputsBuilder.add(inputArtifact);
      }
      updateInputs(inputsBuilder.build());
    } catch (IOException e) {
      // Some kind of IO or parse exception--wrap & rethrow it to stop the build.
      throw new EnvironmentalExecException("error while parsing .d file: " + e.getMessage(), e);
    }
  }

  @Override
  public boolean discoversInputs() {
    return depFile != null || !orderOnlyInputs.isEmpty();
  }

  @Override
  public NestedSet<Artifact> getAllowedDerivedInputs() {
    return getInputs();
  }

  @Override
  public NestedSet<Artifact> discoverInputs(ActionExecutionContext actionExecutionContext) {
    NestedSet<Artifact> inputs =
        NestedSetBuilder.<Artifact>stableOrder()
            .addTransitive(getInputs())
            .addTransitive(orderOnlyInputs)
            .build();
    updateInputs(inputs);
    return inputs;
  }
}
