// 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.skylark;

import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.AliasProvider;
import com.google.devtools.build.lib.analysis.CommandHelper;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.LocationExpander;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.configuredtargets.AbstractConfiguredTarget;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.ParamType;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.syntax.BuiltinFunction;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.EvalUtils;
import com.google.devtools.build.lib.syntax.Printer;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.SkylarkSemantics;
import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.syntax.Type.ConversionException;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// TODO(bazel-team): function argument names are often duplicated,
// figure out a nicely readable way to get rid of the duplications.
/**
 * A helper class to provide an easier API for Skylark rule implementations
 * and hide the original Java API. This is experimental code.
 */
public class SkylarkRuleImplementationFunctions {

  // TODO(bazel-team): add all the remaining parameters
  // TODO(bazel-team): merge executable and arguments
  /**
   * A Skylark built-in function to create and register a SpawnAction using a dictionary of
   * parameters: action( inputs = [input1, input2, ...], outputs = [output1, output2, ...],
   * executable = executable, arguments = [argument1, argument2, ...], mnemonic = 'Mnemonic',
   * command = 'command', )
   */
  @SkylarkSignature(
    name = "action",
    doc =
        "DEPRECATED. Use <a href=\"actions.html#run\">ctx.actions.run()</a> or"
            + " <a href=\"actions.html#run_shell\">ctx.actions.run_shell()</a>. <br>"
            + "Creates an action that runs an executable or a shell command."
            + " You must specify either <code>command</code> or <code>executable</code>.\n"
            + "Actions and genrules are very similar, but have different use cases. Actions are "
            + "used inside rules, and genrules are used inside macros. Genrules also have make "
            + "variable expansion.",
    objectType = SkylarkRuleContext.class,
    returnType = Runtime.NoneType.class,
    parameters = {
      @Param(name = "self", type = SkylarkRuleContext.class, doc = "This RuleContext."),
      @Param(
        name = "outputs",
        type = SkylarkList.class,
        generic1 = Artifact.class,
        named = true,
        positional = false,
        doc = "List of the output files of the action."
      ),
      @Param(
        name = "inputs",
        allowedTypes = {
          @ParamType(type = SkylarkList.class),
          @ParamType(type = SkylarkNestedSet.class),
        },
        generic1 = Artifact.class,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc = "List of the input files of the action."
      ),
      @Param(
        name = "executable",
        type = Object.class,
        allowedTypes = {
          @ParamType(type = Artifact.class),
          @ParamType(type = String.class),
          @ParamType(type = Runtime.NoneType.class),
        },
        defaultValue = "None",
        named = true,
        positional = false,
        doc = "The executable file to be called by the action."
      ),
      @Param(
        name = "arguments",
        allowedTypes = {
          @ParamType(type = SkylarkList.class),
        },
        defaultValue = "[]",
        named = true,
        positional = false,
        doc =
            "Command line arguments of the action."
                + "Must be a list of strings or actions.args() objects."
      ),
      @Param(
        name = "mnemonic",
        type = String.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = "A one-word description of the action, e.g. CppCompile or GoLink."
      ),
      @Param(
        name = "command",
        type = Object.class,
        allowedTypes = {
          @ParamType(type = String.class),
          @ParamType(type = SkylarkList.class, generic1 = String.class),
          @ParamType(type = Runtime.NoneType.class),
        },
        defaultValue = "None",
        named = true,
        positional = false,
        doc =
            "Shell command to execute. It is usually preferable to "
                + "use <code>executable</code> instead. "
                + "Arguments are available with <code>$1</code>, <code>$2</code>, etc."
      ),
      @Param(
        name = "progress_message",
        type = String.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc =
            "Progress message to show to the user during the build, "
                + "e.g. \"Compiling foo.cc to create foo.o\"."
      ),
      @Param(
        name = "use_default_shell_env",
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = "Whether the action should use the built in shell environment or not."
      ),
      @Param(
        name = "env",
        type = SkylarkDict.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = "Sets the dictionary of environment variables."
      ),
      @Param(
        name = "execution_requirements",
        type = SkylarkDict.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc =
            "Information for scheduling the action. See "
                + "<a href=\"$BE_ROOT/common-definitions.html#common.tags\">tags</a> "
                + "for useful keys."
      ),
      @Param(
        // TODO(bazel-team): The name here isn't accurate anymore. This is technically experimental,
        // so folks shouldn't be too attached, but consider renaming to be more accurate/opaque.
        name = "input_manifests",
        type = SkylarkList.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc =
            "(Experimental) sets the input runfiles metadata; "
                + "they are typically generated by resolve_command."
      )
    },
    useLocation = true,
    useEnvironment = true
  )
  private static final BuiltinFunction createSpawnAction =
      new BuiltinFunction("action") {
        public Runtime.NoneType invoke(
            SkylarkRuleContext ctx,
            SkylarkList outputs,
            Object inputs,
            Object executableUnchecked,
            Object arguments,
            Object mnemonicUnchecked,
            Object commandUnchecked,
            Object progressMessage,
            Boolean useDefaultShellEnv,
            Object envUnchecked,
            Object executionRequirementsUnchecked,
            Object inputManifestsUnchecked,
            Location loc,
            Environment env)
            throws EvalException {
          checkDeprecated(
              "ctx.actions.run or ctx.actions.run_shell", "ctx.action", loc, env.getSemantics());
          ctx.checkMutable("action");
          if ((commandUnchecked == Runtime.NONE) == (executableUnchecked == Runtime.NONE)) {
            throw new EvalException(
                loc, "You must specify either 'command' or 'executable' argument");
          }
          boolean hasCommand = commandUnchecked != Runtime.NONE;
          if (!hasCommand) {
            ctx.actions()
                .run(
                    outputs,
                    inputs,
                    executableUnchecked,
                    arguments,
                    mnemonicUnchecked,
                    progressMessage,
                    useDefaultShellEnv,
                    envUnchecked,
                    executionRequirementsUnchecked,
                    inputManifestsUnchecked);

          } else {
            ctx.actions()
                .runShell(
                    outputs,
                    inputs,
                    arguments,
                    mnemonicUnchecked,
                    commandUnchecked,
                    progressMessage,
                    useDefaultShellEnv,
                    envUnchecked,
                    executionRequirementsUnchecked,
                    inputManifestsUnchecked);
          }
          return Runtime.NONE;
        }
      };

  static void checkDeprecated(
      String newApi, String oldApi, Location loc, SkylarkSemantics semantics)
      throws EvalException {
    if (semantics.incompatibleNewActionsApi()) {
      throw new EvalException(
          loc,
          "Use " + newApi + " instead of " + oldApi + ". \n"
              + "Use --incompatible_new_actions_api=false to temporarily disable this check.");
    }
  }

  @SkylarkSignature(
    name = "expand_location",
    doc =
        "Expands all <code>$(location ...)</code> templates in the given string by replacing "
            + "<code>$(location //x)</code> with the path of the output file of target //x. "
            + "Expansion only works for labels that point to direct dependencies of this rule or "
            + "that are explicitly listed in the optional argument <code>targets</code>. "
            + "<br/><br/>"
            + "<code>$(location ...)</code> will cause an error if the referenced target has "
            + "multiple outputs. In this case, please use <code>$(locations ...)</code> since it "
            + "produces a space-separated list of output paths. It can be safely used for a "
            + "single output file, too.",
    objectType = SkylarkRuleContext.class,
    returnType = String.class,
    parameters = {
      @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
      @Param(name = "input", type = String.class, doc = "String to be expanded."),
      @Param(
        name = "targets",
        type = SkylarkList.class,
        generic1 = AbstractConfiguredTarget.class,
        defaultValue = "[]",
        doc = "List of targets for additional lookup information."
      ),
    },
    useLocation = true,
    useEnvironment = true
  )
  private static final BuiltinFunction expandLocation =
      new BuiltinFunction("expand_location") {
        @SuppressWarnings("unused")
        public String invoke(
            SkylarkRuleContext ctx,
            String input,
            SkylarkList targets,
            Location loc,
            Environment env)
            throws EvalException {
          ctx.checkMutable("expand_location");
          try {
            return LocationExpander.withExecPaths(
                    ctx.getRuleContext(),
                    makeLabelMap(targets.getContents(TransitiveInfoCollection.class, "targets")))
                .expand(input);
          } catch (IllegalStateException ise) {
            throw new EvalException(loc, ise);
          }
        }
      };

  /**
   * Builds a map: Label -> List of files from the given labels
   *
   * @param knownLabels List of known labels
   * @return Immutable map with immutable collections as values
   */
  private static ImmutableMap<Label, ImmutableCollection<Artifact>> makeLabelMap(
      Iterable<TransitiveInfoCollection> knownLabels) {
    ImmutableMap.Builder<Label, ImmutableCollection<Artifact>> builder = ImmutableMap.builder();

    for (TransitiveInfoCollection current : knownLabels) {
      builder.put(
          AliasProvider.getDependencyLabel(current),
          ImmutableList.copyOf(current.getProvider(FileProvider.class).getFilesToBuild()));
    }

    return builder.build();
  }

  @SkylarkSignature(
    name = "file_action",
    doc = "DEPRECATED. Use <a href =\"actions.html#write\">ctx.actions.write</a> instead. <br>"
        + "Creates a file write action.",
    objectType = SkylarkRuleContext.class,
    returnType = Runtime.NoneType.class,
    parameters = {
      @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
      @Param(name = "output", type = Artifact.class, doc = "The output file."),
      @Param(name = "content", type = String.class, doc = "The contents of the file."),
      @Param(
        name = "executable",
        type = Boolean.class,
        defaultValue = "False",
        doc = "Whether the output file should be executable (default is False)."
      )
    },
    useLocation = true,
    useEnvironment = true
  )
  private static final BuiltinFunction createFileWriteAction =
      new BuiltinFunction("file_action") {
        public Runtime.NoneType invoke(
            SkylarkRuleContext ctx, Artifact output, String content, Boolean executable,
            Location loc, Environment env)
            throws EvalException {
          checkDeprecated("ctx.actions.write", "ctx.file_action", loc, env.getSemantics());
          ctx.checkMutable("file_action");
          ctx.actions().write(output, content, executable);
          return Runtime.NONE;
        }
      };

  @SkylarkSignature(
    name = "empty_action",
    doc =
        "DEPRECATED. Use <a href=\"actions.html#do_nothing\">ctx.actions.do_nothing</a> instead."
            + " <br>"
            + "Creates an empty action that neither executes a command nor produces any "
            + "output, but that is useful for inserting 'extra actions'.",
    objectType = SkylarkRuleContext.class,
    returnType = Runtime.NoneType.class,
    parameters = {
      @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
      @Param(
        name = "mnemonic",
        type = String.class,
        named = true,
        positional = false,
        doc = "A one-word description of the action, e.g. CppCompile or GoLink."
      ),
      @Param(
        name = "inputs",
        allowedTypes = {
          @ParamType(type = SkylarkList.class),
          @ParamType(type = SkylarkNestedSet.class),
        },
        generic1 = Artifact.class,
        named = true,
        positional = false,
        defaultValue = "[]",
        doc = "List of the input files of the action."
      ),
    },
    useLocation = true,
    useEnvironment = true
  )
  private static final BuiltinFunction createEmptyAction =
      new BuiltinFunction("empty_action") {
        @SuppressWarnings("unused")
        public Runtime.NoneType invoke(SkylarkRuleContext ctx, String mnemonic, Object inputs,
            Location loc, Environment env)
            throws EvalException {
          checkDeprecated("ctx.actions.do_nothing", "ctx.empty_action", loc, env.getSemantics());
          ctx.checkMutable("empty_action");
          ctx.actions().doNothing(mnemonic, inputs);
          return Runtime.NONE;
        }
      };

  @SkylarkSignature(
    name = "template_action",
    doc = "DEPRECATED. "
        + "Use <a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a> instead."
        + "<br>Creates a template expansion action.",
    objectType = SkylarkRuleContext.class,
    returnType = Runtime.NoneType.class,
    parameters = {
      @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
      @Param(
        name = "template",
        type = Artifact.class,
        named = true,
        positional = false,
        doc = "The template file, which is a UTF-8 encoded text file."
      ),
      @Param(
        name = "output",
        type = Artifact.class,
        named = true,
        positional = false,
        doc = "The output file, which is a UTF-8 encoded text file."
      ),
      @Param(
        name = "substitutions",
        type = SkylarkDict.class,
        named = true,
        positional = false,
        doc = "Substitutions to make when expanding the template."
      ),
      @Param(
        name = "executable",
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = "Whether the output file should be executable (default is False)."
      )
    },
    useLocation = true,
    useEnvironment = true
  )
  private static final BuiltinFunction createTemplateAction =
      new BuiltinFunction("template_action", Arrays.<Object>asList(false)) {
        public Runtime.NoneType invoke(
            SkylarkRuleContext ctx,
            Artifact template,
            Artifact output,
            SkylarkDict<?, ?> substitutionsUnchecked,
            Boolean executable, Location loc, Environment env)
            throws EvalException {
          checkDeprecated("ctx.actions.expand_template", "ctx.template_action", loc,
              env.getSemantics());
          ctx.checkMutable("template_action");
          ctx.actions().expandTemplate(template, output, substitutionsUnchecked, executable);
          return Runtime.NONE;
        }
      };

  // TODO(bazel-team): Remove runfile states from Skylark.
  @SkylarkSignature(name = "runfiles",
      doc = "Creates a runfiles object.",
      objectType = SkylarkRuleContext.class,
      returnType = Runfiles.class,
      parameters = {
        @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
        @Param(name = "files", type = SkylarkList.class, generic1 = Artifact.class,
            defaultValue = "[]", doc = "The list of files to be added to the runfiles."),
        // TODO(bazel-team): If we have a memory efficient support for lazy list containing
        // NestedSets we can remove this and just use files = [file] + list(set)
        // Also, allow empty set for init
        @Param(name = "transitive_files", type = SkylarkNestedSet.class, generic1 = Artifact.class,
            noneable = true, defaultValue = "None",
            doc = "The (transitive) set of files to be added to the runfiles. The depset should "
            + "use the `default` order (which, as the name implies, is the default)."),
        @Param(name = "collect_data", type = Boolean.class, defaultValue = "False",
            doc = "Whether to collect the data "
            + "runfiles from the dependencies in srcs, data and deps attributes."),
        @Param(name = "collect_default", type = Boolean.class, defaultValue = "False",
            doc = "Whether to collect the default "
            + "runfiles from the dependencies in srcs, data and deps attributes."),
        @Param(name = "symlinks", type = SkylarkDict.class, defaultValue = "{}",
            doc = "The map of symlinks to be added to the runfiles, prefixed by workspace name."),
        @Param(name = "root_symlinks", type = SkylarkDict.class, defaultValue = "{}",
            doc = "The map of symlinks to be added to the runfiles.")},
      useLocation = true)
  private static final BuiltinFunction runfiles = new BuiltinFunction("runfiles") {
    public Runfiles invoke(SkylarkRuleContext ctx, SkylarkList files, Object transitiveFiles,
        Boolean collectData, Boolean collectDefault,
        SkylarkDict<?, ?> symlinks, SkylarkDict<?, ?> rootSymlinks,
        Location loc) throws EvalException, ConversionException {
      ctx.checkMutable("runfiles");
      Runfiles.Builder builder = new Runfiles.Builder(
          ctx.getRuleContext().getWorkspaceName(),
          ctx.getConfiguration().legacyExternalRunfiles());
      boolean checkConflicts = false;
      if (EvalUtils.toBoolean(collectData)) {
        builder.addRunfiles(ctx.getRuleContext(), RunfilesProvider.DATA_RUNFILES);
      }
      if (EvalUtils.toBoolean(collectDefault)) {
        builder.addRunfiles(ctx.getRuleContext(), RunfilesProvider.DEFAULT_RUNFILES);
      }
      if (!files.isEmpty()) {
        builder.addArtifacts(files.getContents(Artifact.class, "files"));
      }
      if (transitiveFiles != Runtime.NONE) {
        builder.addTransitiveArtifacts(((SkylarkNestedSet) transitiveFiles).getSet(Artifact.class));
      }
      if (!symlinks.isEmpty()) {
        // If Skylark code directly manipulates symlinks, activate more stringent validity checking.
        checkConflicts = true;
        for (Map.Entry<String, Artifact> entry : symlinks.getContents(
            String.class, Artifact.class, "symlinks").entrySet()) {
          builder.addSymlink(PathFragment.create(entry.getKey()), entry.getValue());
        }
      }
      if (!rootSymlinks.isEmpty()) {
        checkConflicts = true;
        for (Map.Entry<String, Artifact> entry : rootSymlinks.getContents(
            String.class, Artifact.class, "root_symlinks").entrySet()) {
          builder.addRootSymlink(PathFragment.create(entry.getKey()), entry.getValue());
        }
      }
      Runfiles runfiles = builder.build();
      if (checkConflicts) {
        runfiles.setConflictPolicy(Runfiles.ConflictPolicy.ERROR);
      }
      return runfiles;
    }
  };

  /**
   * Ensures the given {@link Map} has keys that have {@link Label} type and values that have either
   * {@link Iterable} or {@link SkylarkNestedSet} type, and raises {@link EvalException} otherwise.
   * Returns a corresponding map where any sets are replaced by iterables.
   */
  // TODO(bazel-team): find a better way to typecheck this argument.
  @SuppressWarnings("unchecked")
  private static Map<Label, Iterable<Artifact>> checkLabelDict(
      Map<?, ?> labelDict, Location loc, Environment env) throws EvalException {
    Map<Label, Iterable<Artifact>> convertedMap = new HashMap<>();
    for (Map.Entry<?, ?> entry : labelDict.entrySet()) {
      Object key = entry.getKey();
      if (!(key instanceof Label)) {
        throw new EvalException(
            loc, Printer.format("invalid key %r in 'label_dict'", key));
      }
      ImmutableList.Builder<Artifact> files = ImmutableList.builder();
      Object val = entry.getValue();
      Iterable<?> valIter;
      try {
        valIter = EvalUtils.toIterableStrict(val, loc, env);
      } catch (EvalException ex) {
        // EvalException is thrown only if the type is wrong.
        throw new EvalException(
            loc, Printer.format("invalid value %r in 'label_dict': " + ex, val));
      }
      for (Object file : valIter) {
        if (!(file instanceof Artifact)) {
          throw new EvalException(
              loc, Printer.format("invalid value %r in 'label_dict'", val));
        }
        files.add((Artifact) file);
      }
      convertedMap.put((Label) key, files.build());
    }
    return convertedMap;
  }

  /** suffix of script to be used in case the command is too long to fit on a single line */
  private static final String SCRIPT_SUFFIX = ".script.sh";

  @SkylarkSignature(
    name = "resolve_command",
    // TODO(bazel-team): The naming here isn't entirely accurate (input_manifests is no longer
    // manifests), but this is experimental/should be opaque to the end user.
    doc =
        "<i>(Experimental)</i> "
            + "Returns a tuple <code>(inputs, command, input_manifests)</code> of the list of "
            + "resolved inputs, the argv list for the resolved command, and the runfiles metadata"
            + "required to run the command, all of them suitable for passing as the same-named "
            + "arguments of the <code>ctx.action</code> method.",
    objectType = SkylarkRuleContext.class,
    returnType = Tuple.class,
    parameters = {
      @Param(name = "self", type = SkylarkRuleContext.class, doc = "This RuleContext."),
      @Param(
        name = "command",
        type = String.class, // string
        defaultValue = "''",
        named = true,
        positional = false,
        doc = "Command to resolve."
      ),
      @Param(
        name = "attribute",
        type = String.class, // string
        defaultValue = "None",
        noneable = true,
        named = true,
        positional = false,
        doc = "Name of the associated attribute for which to issue an error, or None."
      ),
      @Param(
        name = "expand_locations",
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc =
            "Shall we expand $(location) variables? "
                + "See <a href=\"#expand_location\">ctx.expand_location()</a> for more details."
      ),
      @Param(
        name = "make_variables",
        type = SkylarkDict.class, // dict(string, string)
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = "Make variables to expand, or None."
      ),
      @Param(
        name = "tools",
        defaultValue = "[]",
        type = SkylarkList.class,
        generic1 = TransitiveInfoCollection.class,
        named = true,
        positional = false,
        doc = "List of tools (list of targets)."
      ),
      @Param(
        name = "label_dict",
        type = SkylarkDict.class,
        defaultValue = "{}",
        named = true,
        positional = false,
        doc =
            "Dictionary of resolved labels and the corresponding list of Files "
                + "(a dict of Label : list of Files)."
      ),
      @Param(
        name = "execution_requirements",
        type = SkylarkDict.class,
        defaultValue = "{}",
        named = true,
        positional = false,
        doc =
            "Information for scheduling the action to resolve this command. See "
                + "<a href=\"$BE_ROOT/common-definitions.html#common.tags\">tags</a> "
                + "for useful keys."
      ),
    },
    useLocation = true,
    useEnvironment = true
  )
  private static final BuiltinFunction resolveCommand =
      new BuiltinFunction("resolve_command") {
        @SuppressWarnings("unchecked")
        public Tuple<Object> invoke(
            SkylarkRuleContext ctx,
            String command,
            Object attributeUnchecked,
            Boolean expandLocations,
            Object makeVariablesUnchecked,
            SkylarkList tools,
            SkylarkDict<?, ?> labelDictUnchecked,
            SkylarkDict<?, ?> executionRequirementsUnchecked,
            Location loc,
            Environment env)
            throws ConversionException, EvalException {
          ctx.checkMutable("resolve_command");
          Label ruleLabel = ctx.getLabel();
          Map<Label, Iterable<Artifact>> labelDict = checkLabelDict(labelDictUnchecked, loc, env);
          // The best way to fix this probably is to convert CommandHelper to Skylark.
          CommandHelper helper =
              new CommandHelper(
                  ctx.getRuleContext(),
                  tools.getContents(TransitiveInfoCollection.class, "tools"),
                  ImmutableMap.copyOf(labelDict));
          String attribute =
              Type.STRING.convertOptional(attributeUnchecked, "attribute", ruleLabel);
          if (expandLocations) {
            command = helper.resolveCommandAndExpandLabels(
                command, attribute, /*allowDataInLabel=*/false);
          }
          if (!EvalUtils.isNullOrNone(makeVariablesUnchecked)) {
            Map<String, String> makeVariables =
                Type.STRING_DICT.convert(makeVariablesUnchecked, "make_variables", ruleLabel);
            command = ctx.expandMakeVariables(attribute, command, makeVariables);
          }
          List<Artifact> inputs = new ArrayList<>();
          inputs.addAll(helper.getResolvedTools());

          ImmutableMap<String, String> executionRequirements =
              ImmutableMap.copyOf(
                  SkylarkDict.castSkylarkDictOrNoneToDict(
                      executionRequirementsUnchecked,
                      String.class,
                      String.class,
                      "execution_requirements"));
          List<String> argv =
              helper.buildCommandLine(command, inputs, SCRIPT_SUFFIX, executionRequirements);
          return Tuple.<Object>of(
              MutableList.copyOf(env, inputs),
              MutableList.copyOf(env, argv),
              helper.getToolsRunfilesSuppliers());
        }
      };

  static {
    SkylarkSignatureProcessor.configureSkylarkFunctions(SkylarkRuleImplementationFunctions.class);
  }
}
