// 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 com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.actions.CommandLine;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.collect.CollectionUtils;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType;
import com.google.devtools.build.lib.rules.cpp.Link.LinkerOrArchiver;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;

/**
 * Represents the command line of a linker invocation. It supports executables and dynamic libraries
 * as well as static libraries.
 */
@AutoCodec
@Immutable
public final class LinkCommandLine extends CommandLine {
  private final String actionName;
  private final String forcedToolPath;
  private final CcToolchainVariables variables;
  // The feature config can be null for tests.
  @Nullable private final FeatureConfiguration featureConfiguration;
  private final ImmutableList<Artifact> buildInfoHeaderArtifacts;
  private final Iterable<Artifact> linkerInputArtifacts;
  private final LinkTargetType linkTargetType;
  private final Link.LinkingMode linkingMode;
  @Nullable private final PathFragment toolchainLibrariesSolibDir;
  private final boolean nativeDeps;
  private final boolean useTestOnlyFlags;

  @Nullable private final Artifact paramFile;

  @VisibleForSerialization
  LinkCommandLine(
      String actionName,
      String forcedToolPath,
      ImmutableList<Artifact> buildInfoHeaderArtifacts,
      Iterable<Artifact> linkerInputArtifacts,
      LinkTargetType linkTargetType,
      Link.LinkingMode linkingMode,
      @Nullable PathFragment toolchainLibrariesSolibDir,
      boolean nativeDeps,
      boolean useTestOnlyFlags,
      @Nullable Artifact paramFile,
      CcToolchainVariables variables,
      @Nullable FeatureConfiguration featureConfiguration) {

    this.actionName = actionName;
    this.forcedToolPath = forcedToolPath;
    this.variables = variables;
    this.featureConfiguration = featureConfiguration;
    this.buildInfoHeaderArtifacts = Preconditions.checkNotNull(buildInfoHeaderArtifacts);
    this.linkerInputArtifacts = Preconditions.checkNotNull(linkerInputArtifacts);
    this.linkTargetType = Preconditions.checkNotNull(linkTargetType);
    this.linkingMode = Preconditions.checkNotNull(linkingMode);
    this.toolchainLibrariesSolibDir = toolchainLibrariesSolibDir;
    this.nativeDeps = nativeDeps;
    this.useTestOnlyFlags = useTestOnlyFlags;
    this.paramFile = paramFile;
  }

  @Nullable
  public Artifact getParamFile() {
    return paramFile;
  }

  /** See {@link CppLinkAction#getBuildInfoHeaderArtifacts()} */
  public ImmutableList<Artifact> getBuildInfoHeaderArtifacts() {
    return buildInfoHeaderArtifacts;
  }

  /** Returns the (ordered, immutable) list of paths to the linker's input files. */
  public Iterable<Artifact> getLinkerInputArtifacts() {
    return linkerInputArtifacts;
  }

  /**
   * Returns the current type of link target set.
   */
  public LinkTargetType getLinkTargetType() {
    return linkTargetType;
  }

  /** Returns the "staticness" of the link. */
  public Link.LinkingMode getLinkingMode() {
    return linkingMode;
  }

  /**
   * Returns the additional linker options for this link.
   */
  public ImmutableList<String> getLinkopts() {
    if (variables.isAvailable(LinkBuildVariables.USER_LINK_FLAGS.getVariableName())) {
      return CcToolchainVariables.toStringList(
          variables, LinkBuildVariables.USER_LINK_FLAGS.getVariableName());
    } else {
      return ImmutableList.of();
    }
  }

  /** Returns the path to the linker. */
  public String getLinkerPathString() {
    return featureConfiguration.getToolPathForAction(linkTargetType.getActionName());
  }

  /**
   * Returns the location of the C++ runtime solib symlinks. If null, the C++ dynamic runtime
   * libraries either do not exist (because they do not come from the depot) or they are in the
   * regular solib directory.
   */
  @Nullable
  public PathFragment getToolchainLibrariesSolibDir() {
    return toolchainLibrariesSolibDir;
  }

  /**
   * Returns true for libraries linked as native dependencies for other languages.
   */
  public boolean isNativeDeps() {
    return nativeDeps;
  }

  /**
   * Returns true if this link should use test-specific flags (e.g. $EXEC_ORIGIN as the root for
   * finding shared libraries or lazy binding);  false by default.  See bug "Please use
   * $EXEC_ORIGIN instead of $ORIGIN when linking cc_tests" for further context.
   */
  public boolean useTestOnlyFlags() {
    return useTestOnlyFlags;
  }

  /** Returns the build variables used to template the crosstool for this linker invocation. */
  @VisibleForTesting
  public CcToolchainVariables getBuildVariables() {
    return this.variables;
  }

  /**
   * Splits the link command-line into a part to be written to a parameter file, and the remaining
   * actual command line to be executed (which references the parameter file). Should only be used
   * if getParamFile() is not null.
   */
  @VisibleForTesting
  final Pair<List<String>, List<String>> splitCommandline() {
    return splitCommandline(paramFile, getRawLinkArgv(null), linkTargetType);
  }

  @VisibleForTesting
  final Pair<List<String>, List<String>> splitCommandline(@Nullable ArtifactExpander expander) {
    return splitCommandline(paramFile, getRawLinkArgv(expander), linkTargetType);
  }

  private static Pair<List<String>, List<String>> splitCommandline(
      Artifact paramFile,
      List<String> args,
      LinkTargetType linkTargetType) {
    Preconditions.checkNotNull(paramFile);
    if (linkTargetType.linkerOrArchiver() == LinkerOrArchiver.ARCHIVER) {
      // Ar link commands can also generate huge command lines.
      List<String> paramFileArgs = new ArrayList<>();
      List<String> commandlineArgs = new ArrayList<>();
      extractArgumentsForStaticLinkParamFile(args, commandlineArgs, paramFileArgs);
      return Pair.of(commandlineArgs, paramFileArgs);
    } else {
      // Gcc link commands tend to generate humongous commandlines for some targets, which may
      // not fit on some remote execution machines. To work around this we will employ the help of
      // a parameter file and pass any linker options through it.
      List<String> paramFileArgs = new ArrayList<>();
      List<String> commandlineArgs = new ArrayList<>();
      extractArgumentsForDynamicLinkParamFile(args, commandlineArgs, paramFileArgs);

      return Pair.of(commandlineArgs, paramFileArgs);
    }
  }

  /**
   * A {@link CommandLine} implementation that returns the command line args pertaining to the
   * .params file.
   */
  @AutoCodec
  @VisibleForSerialization
  static class ParamFileCommandLine extends CommandLine {
    private final Artifact paramsFile;
    private final LinkTargetType linkTargetType;
    private final String forcedToolPath;
    private final FeatureConfiguration featureConfiguration;
    private final String actionName;
    private final CcToolchainVariables variables;

    public ParamFileCommandLine(
        Artifact paramsFile,
        LinkTargetType linkTargetType,
        String forcedToolPath,
        FeatureConfiguration featureConfiguration,
        String actionName,
        CcToolchainVariables variables) {
      this.paramsFile = paramsFile;
      this.linkTargetType = linkTargetType;
      this.forcedToolPath = forcedToolPath;
      this.featureConfiguration = featureConfiguration;
      this.actionName = actionName;
      this.variables = variables;
    }

    @Override
    public Iterable<String> arguments() {
      List<String> argv =
          getRawLinkArgv(
              null,
              forcedToolPath,
              featureConfiguration,
              actionName,
              linkTargetType,
              variables);
      return splitCommandline(paramsFile, argv, linkTargetType).getSecond();
    }

    @Override
    public Iterable<String> arguments(ArtifactExpander expander) {
      List<String> argv =
          getRawLinkArgv(
              expander,
              forcedToolPath,
              featureConfiguration,
              actionName,
              linkTargetType,
              variables);
      return splitCommandline(paramsFile, argv, linkTargetType).getSecond();
    }
  }

  /**
   * Returns just the .params file portion of the command-line as a {@link CommandLine}.
   */
  CommandLine paramCmdLine() {
    Preconditions.checkNotNull(paramFile);
    return new ParamFileCommandLine(
        paramFile,
        linkTargetType,
        forcedToolPath,
        featureConfiguration,
        actionName,
        variables);
  }

  public static void extractArgumentsForStaticLinkParamFile(
      List<String> args, List<String> commandlineArgs, List<String> paramFileArgs) {
    commandlineArgs.add(args.get(0)); // ar command, must not be moved!
    int argsSize = args.size();
    for (int i = 1; i < argsSize; i++) {
      String arg = args.get(i);
      if (arg.startsWith("@")) {
        commandlineArgs.add(arg); // params file, keep it in the command line
      } else {
        paramFileArgs.add(arg); // the rest goes to the params file
      }
    }
  }

  public static void extractArgumentsForDynamicLinkParamFile(
      List<String> args, List<String> commandlineArgs, List<String> paramFileArgs) {
    // Note, that it is not important that all linker arguments are extracted so that
    // they can be moved into a parameter file, but the vast majority should.
    commandlineArgs.add(args.get(0));   // gcc command, must not be moved!
    int argsSize = args.size();
    for (int i = 1; i < argsSize; i++) {
      String arg = args.get(i);
      if (arg.equals("-Wl,-no-whole-archive")) {
        paramFileArgs.add("-no-whole-archive");
      } else if (arg.equals("-Wl,-whole-archive")) {
        paramFileArgs.add("-whole-archive");
      } else if (arg.equals("-Wl,--start-group")) {
        paramFileArgs.add("--start-group");
      } else if (arg.equals("-Wl,--end-group")) {
        paramFileArgs.add("--end-group");
      } else if (arg.equals("-Wl,--start-lib")) {
        paramFileArgs.add("--start-lib");
      } else if (arg.equals("-Wl,--end-lib")) {
        paramFileArgs.add("--end-lib");
      } else if (arg.charAt(0) == '-') {
        if (arg.startsWith("-l")) {
          paramFileArgs.add(arg);
        } else {
          // Anything else starting with a '-' can stay on the commandline.
          commandlineArgs.add(arg);
          if (arg.equals("-o")) {
            // Special case for '-o': add the following argument as well - it is the output file!
            commandlineArgs.add(args.get(++i));
          }
        }
      } else if (CppFileTypes.OBJECT_FILE.apply(arg)
          || CppFileTypes.PIC_OBJECT_FILE.apply(arg)
          || CppFileTypes.ARCHIVE.apply(arg)
          || CppFileTypes.PIC_ARCHIVE.apply(arg)
          || CppFileTypes.ALWAYS_LINK_LIBRARY.apply(arg)
          || CppFileTypes.ALWAYS_LINK_PIC_LIBRARY.apply(arg)
          || CppFileTypes.SHARED_LIBRARY.apply(arg)
          || CppFileTypes.INTERFACE_SHARED_LIBRARY.apply(arg)
          || CppFileTypes.VERSIONED_SHARED_LIBRARY.apply(arg)) {
        // All objects of any kind go into the linker parameters.
        paramFileArgs.add(arg);
      } else {
        // Everything that's left stays conservatively on the commandline.
        commandlineArgs.add(arg);
      }
    }
  }

  /**
   * Returns a raw link command for the given link invocation, including both command and arguments
   * (argv). The version that uses the expander is preferred, but that one can't be used during
   * analysis.
   *
   * @return raw link command line.
   */
  public List<String> getRawLinkArgv() {
    return getRawLinkArgv(null);
  }

  /**
   * Returns a raw link command for the given link invocation, including both command and arguments
   * (argv).
   *
   * @param expander ArtifactExpander for expanding TreeArtifacts.
   * @return raw link command line.
   */
  public List<String> getRawLinkArgv(@Nullable ArtifactExpander expander) {
    return getRawLinkArgv(
        expander,
        forcedToolPath,
        featureConfiguration,
        actionName,
        linkTargetType,
        variables);
  }

  private static List<String> getRawLinkArgv(
      @Nullable ArtifactExpander expander,
      String forcedToolPath,
      FeatureConfiguration featureConfiguration,
      String actionName,
      LinkTargetType linkTargetType,
      CcToolchainVariables variables) {
    List<String> argv = new ArrayList<>();
    if (forcedToolPath != null) {
      argv.add(forcedToolPath);
    } else {
      Preconditions.checkArgument(
          featureConfiguration.actionIsConfigured(actionName),
          String.format("Expected action_config for '%s' to be configured", actionName));
      argv.add(featureConfiguration.getToolPathForAction(linkTargetType.getActionName()));
    }
    argv.addAll(featureConfiguration.getCommandLine(actionName, variables, expander));
    return argv;
  }

  List<String> getCommandLine(@Nullable ArtifactExpander expander) {
    // Try to shorten the command line by use of a parameter file.
    // This makes the output with --subcommands (et al) more readable.
    if (paramFile != null) {
      Pair<List<String>, List<String>> split = splitCommandline(expander);
      return split.first;
    } else {
      return getRawLinkArgv(expander);
    }
  }

  @Override
  public List<String> arguments() {
    return getRawLinkArgv(null);
  }

  @Override
  public Iterable<String> arguments(ArtifactExpander artifactExpander) {
    return getRawLinkArgv(artifactExpander);
  }

  /** A builder for a {@link LinkCommandLine}. */
  public static final class Builder {

    private final RuleContext ruleContext;
    private String forcedToolPath;
    private ImmutableList<Artifact> buildInfoHeaderArtifacts = ImmutableList.of();
    private Iterable<Artifact> linkerInputArtifacts = ImmutableList.of();
    @Nullable private LinkTargetType linkTargetType;
    private Link.LinkingMode linkingMode = Link.LinkingMode.STATIC;
    @Nullable private PathFragment toolchainLibrariesSolibDir;
    private boolean nativeDeps;
    private boolean useTestOnlyFlags;
    @Nullable private Artifact paramFile;
    private CcToolchainVariables variables;
    private FeatureConfiguration featureConfiguration;

    public Builder(RuleContext ruleContext) {
      this.ruleContext = ruleContext;
    }

    public LinkCommandLine build() {

      if (linkTargetType.linkerOrArchiver() == LinkerOrArchiver.ARCHIVER) {
        Preconditions.checkArgument(
            buildInfoHeaderArtifacts.isEmpty(),
            "build info headers may only be present on dynamic library or executable links");
      }

      // The ruleContext can be null for some tests.
      if (ruleContext != null) {
        Preconditions.checkNotNull(featureConfiguration);
      }

      if (variables == null) {
        variables = CcToolchainVariables.EMPTY;
      }

      String actionName = linkTargetType.getActionName();

      return new LinkCommandLine(
          actionName,
          forcedToolPath,
          buildInfoHeaderArtifacts,
          linkerInputArtifacts,
          linkTargetType,
          linkingMode,
          toolchainLibrariesSolibDir,
          nativeDeps,
          useTestOnlyFlags,
          paramFile,
          variables,
          featureConfiguration);
    }

    /** Use given tool path instead of the one from feature configuration */
    public Builder forceToolPath(String forcedToolPath) {
      this.forcedToolPath = forcedToolPath;
      return this;
    }

    /** Sets the feature configuration for this link action. */
    public Builder setFeatureConfiguration(FeatureConfiguration featureConfiguration) {
      this.featureConfiguration = featureConfiguration;
      return this;
    }

    /**
     * Sets the type of the link. It is an error to try to set this to {@link
     * LinkTargetType#INTERFACE_DYNAMIC_LIBRARY}. Note that all the static target types (see {@link
     * LinkTargetType#linkerOrArchiver}) are equivalent, and there is no check that the output
     * artifact matches the target type extension.
     */
    public Builder setLinkTargetType(LinkTargetType linkTargetType) {
      Preconditions.checkArgument(linkTargetType != LinkTargetType.INTERFACE_DYNAMIC_LIBRARY);
      this.linkTargetType = linkTargetType;
      return this;
    }

    /**
     * Sets a list of linker input artifacts. These get turned into linker options depending on the
     * staticness and the target type. This call makes an immutable copy of the inputs, if the
     * provided Iterable isn't already immutable (see {@link CollectionUtils#makeImmutable}).
     */
    public Builder setLinkerInputArtifacts(Iterable<Artifact> linkerInputArtifacts) {
      this.linkerInputArtifacts = CollectionUtils.makeImmutable(linkerInputArtifacts);
      return this;
    }

    /**
     * Sets how static the link is supposed to be. For static target types (see {@link
     * LinkTargetType#linkerOrArchiver()}}), the {@link #build} method throws an exception if this
     * is not {@link LinkingMode#STATIC}. The default setting is {@link LinkingMode#STATIC}.
     */
    public Builder setLinkingMode(Link.LinkingMode linkingMode) {
      this.linkingMode = linkingMode;
      return this;
    }

    /**
     * The build info header artifacts are generated header files that are used for link stamping.
     * The {@link #build} method throws an exception if the build info header artifacts are
     * non-empty for a static link (see {@link LinkTargetType#linkerOrArchiver()}}).
     */
    public Builder setBuildInfoHeaderArtifacts(ImmutableList<Artifact> buildInfoHeaderArtifacts) {
      this.buildInfoHeaderArtifacts = buildInfoHeaderArtifacts;
      return this;
    }

    /**
     * Whether the resulting library is intended to be used as a native library from another
     * programming language. This influences the rpath. The {@link #build} method throws an
     * exception if this is true for a static link (see {@link LinkTargetType#linkerOrArchiver()}}).
     */
    public Builder setNativeDeps(boolean nativeDeps) {
      this.nativeDeps = nativeDeps;
      return this;
    }

    /**
     * Sets whether to use test-specific linker flags, e.g. {@code $EXEC_ORIGIN} instead of
     * {@code $ORIGIN} in the rpath or lazy binding.
     */
    public Builder setUseTestOnlyFlags(boolean useTestOnlyFlags) {
      this.useTestOnlyFlags = useTestOnlyFlags;
      return this;
    }

    public Builder setParamFile(Artifact paramFile) {
      this.paramFile = paramFile;
      return this;
    }

    public Builder setBuildVariables(CcToolchainVariables variables) {
      this.variables = variables;
      return this;
    }

    public Builder setToolchainLibrariesSolibDir(PathFragment toolchainLibrariesSolibDir) {
      this.toolchainLibrariesSolibDir = toolchainLibrariesSolibDir;
      return this;
    }
  }
}
