// 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.analysis.actions;

import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.ActionRegistry;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
import com.google.devtools.build.lib.analysis.RuleErrorConsumer;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
import com.google.devtools.build.lib.vfs.PathFragment;
import javax.annotation.Nullable;

/**
 * Contains all API required to construct actions in the context of some target or an aspect applied
 * to a target. Depend on this interface instead of the full RuleContext to avoid accidental data
 * dependency on attribute values.
 *
 * <p>This a "native" equivalent of Starlark's `ctx.actions`.
 */
public interface ActionConstructionContext extends ActionRegistry {

  /** Returns the bin directory for constructed actions. */
  ArtifactRoot getBinDirectory();

  /** Returns the internal directory (used for middlemen) for constructed actions. */
  ArtifactRoot getMiddlemanDirectory();

  /**
   * Returns the action owner that should be used for the default execution group's execution
   * platform.
   */
  ActionOwner getActionOwner();

  /**
   * Returns the action owner that should be used for actions with the given exec group's execution
   * platform. If an invalid exec group is given, returns null.
   */
  @Nullable
  ActionOwner getActionOwner(String execGroup);

  /** Returns the action key context. */
  ActionKeyContext getActionKeyContext();

  /** Returns the {@link BuildConfigurationValue} for which the given rule is analyzed. */
  BuildConfigurationValue getConfiguration();

  /** The current analysis environment. */
  AnalysisEnvironment getAnalysisEnvironment();

  /**
   * Creates an artifact under a given root with the given root-relative path.
   *
   * <p>Verifies that it is in the root-relative directory corresponding to the package of the rule,
   * thus ensuring that it doesn't clash with other artifacts generated by other rules using this
   * method.
   */
  Artifact.DerivedArtifact getDerivedArtifact(PathFragment rootRelativePath, ArtifactRoot root);

  /**
   * Creates a TreeArtifact under a given root with the given root-relative path.
   *
   * <p>Verifies that it is in the root-relative directory corresponding to the package of the rule,
   * thus ensuring that it doesn't clash with other artifacts generated by other rules using this
   * method.
   */
  SpecialArtifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root);

  /**
   * Returns an artifact that can be an output of shared actions. Only use when there is no other
   * option.
   *
   * <p>This artifact can be created anywhere in the output tree, which, in addition to making
   * sharing possible, opens up the possibility of action conflicts and makes it impossible to infer
   * the label of the rule creating the artifact from the path of the artifact.
   */
  Artifact getShareableArtifact(PathFragment rootRelativePath, ArtifactRoot root);

  /**
   * Returns the implicit output artifact for a given template function. If multiple or no artifacts
   * can be found as a result of the template, an exception is thrown.
   */
  Artifact getImplicitOutputArtifact(ImplicitOutputsFunction function) throws InterruptedException;

  /**
   * Returns an artifact with a given file extension. All other path components are the same as in
   * {@code pathFragment}.
   */
  Artifact.DerivedArtifact getRelatedArtifact(PathFragment pathFragment, String extension);

  /**
   * Creates an artifact in a directory that is unique to the rule, thus guaranteeing that it never
   * clashes with artifacts created by other rules.
   *
   * @param uniqueDirectorySuffix suffix of the directory - it will be prepended
   */
  Artifact getUniqueDirectoryArtifact(String uniqueDirectorySuffix, String relative);

  /**
   * Creates an artifact in a directory that is unique to the rule, thus guaranteeing that it never
   * clashes with artifacts created by other rules.
   *
   * @param uniqueDirectorySuffix suffix of the directory - it will be prepended
   */
  Artifact getUniqueDirectoryArtifact(String uniqueDirectorySuffix, PathFragment relative);

  /**
   * Creates an artifact in a directory that is unique to the rule, thus guaranteeing that it never
   * clashes with artifacts created by other rules.
   */
  Artifact getUniqueDirectoryArtifact(
      String uniqueDirectory, PathFragment relative, ArtifactRoot root);

  /**
   * Returns a path fragment qualified by the rule name and unique fragment to
   * disambiguate artifacts produced from the source file appearing in
   * multiple rules.
   *
   * <p>For example "pkg/dir/name" -> "pkg/&lt;fragment>/rule/dir/name.
   */
  public PathFragment getUniqueDirectory(PathFragment fragment);

  /**
   * Returns the root of either the "bin" or "genfiles" tree, based on this target and the current
   * configuration. The choice of which tree to use is based on the rule with which this target
   * (which must be an OutputFile or a Rule) is associated.
   */
  public ArtifactRoot getBinOrGenfilesDirectory();

  /**
   * Returns the root-relative path fragment under which output artifacts of this rule should go.
   *
   * <p>Note that:
   *
   * <ul>
   *   <li>This doesn't guarantee that there are no clashes with rules in the same package.
   *   <li>If possible, {@link #getPackageRelativeArtifact(PathFragment, ArtifactRoot)} should be
   *       used instead of this method.
   * </ul>
   *
   * Ideally, user-visible artifacts should all have corresponding output file targets, all others
   * should go into a rule-specific directory. {@link #getUniqueDirectoryArtifact(String, String)})
   * ensures that this is the case.
   */
  PathFragment getPackageDirectory();

  /**
   * Creates an artifact in a directory that is unique to the package that contains the rule, thus
   * guaranteeing that it never clashes with artifacts created by rules in other packages.
   */
  Artifact getPackageRelativeArtifact(PathFragment relative, ArtifactRoot root);

  /** Returns the {@link PlatformInfo} describing the target's default execution platform. */
  @Nullable
  PlatformInfo getExecutionPlatform();

  /**
   * Returns the {@link PlatformInfo} describing the given exec group's execution platform. Returns
   * null if a nonexistent {@code execGroup} name is given.
   */
  @Nullable
  PlatformInfo getExecutionPlatform(String execGroup);

  /**
   * Returns the {@link com.google.devtools.build.lib.analysis.RuleErrorConsumer} for reporting rule
   * errors.
   */
  RuleErrorConsumer getRuleErrorConsumer();
}
