// 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.base.Preconditions;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.CoreOptions;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.CcToolchainVariables.SequenceBuilder;
import com.google.devtools.build.lib.vfs.PathFragment;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.StarlarkThread;

/** Enum covering all build variables we create for all various {@link CppLinkAction}. */
public enum LinkBuildVariables {
  /** Entries in the linker runtime search path (usually set by -rpath flag) */
  RUNTIME_LIBRARY_SEARCH_DIRECTORIES("runtime_library_search_directories"),
  /** Entries in the linker search path (usually set by -L flag) */
  LIBRARY_SEARCH_DIRECTORIES("library_search_directories"),
  /** Flags providing files to link as inputs in the linker invocation */
  LIBRARIES_TO_LINK("libraries_to_link"),
  /** Thinlto param file produced by thinlto-indexing action consumed by the final link action. */
  THINLTO_PARAM_FILE("thinlto_param_file"),
  /** Location of def file used on Windows with MSVC */
  DEF_FILE_PATH("def_file_path"),
  /** Location where hinlto should write thinlto_param_file flags when indexing. */
  THINLTO_INDEXING_PARAM_FILE("thinlto_indexing_param_file"),

  THINLTO_PREFIX_REPLACE("thinlto_prefix_replace"),
  /**
   * A build variable to let the LTO indexing step know how to map from the minimized bitcode file
   * to the full bitcode file used by the LTO Backends.
   */
  THINLTO_OBJECT_SUFFIX_REPLACE("thinlto_object_suffix_replace"),
  /**
   * A build variable for the path to the merged object file, which is an object file that is
   * created during the LTO indexing step and needs to be passed to the final link.
   */
  THINLTO_MERGED_OBJECT_FILE("thinlto_merged_object_file"),
  /** Location of linker param file created by bazel to overcome command line length limit */
  LINKER_PARAM_FILE("linker_param_file"),
  /** execpath of the output of the linker. */
  OUTPUT_EXECPATH("output_execpath"),
  /** "yes"|"no" depending on whether interface library should be generated. */
  GENERATE_INTERFACE_LIBRARY("generate_interface_library"),
  /** Path to the interface library builder tool. */
  INTERFACE_LIBRARY_BUILDER("interface_library_builder_path"),
  /** Input for the interface library ifso builder tool. */
  INTERFACE_LIBRARY_INPUT("interface_library_input_path"),
  /** Path where to generate interface library using the ifso builder tool. */
  INTERFACE_LIBRARY_OUTPUT("interface_library_output_path"),
  /** Linker flags coming from the --linkopt or linkopts attribute. */
  USER_LINK_FLAGS("user_link_flags"),
  /** A build variable giving linkstamp paths. */
  LINKSTAMP_PATHS("linkstamp_paths"),
  /** Presence of this variable indicates that PIC code should be generated. */
  FORCE_PIC("force_pic"),
  /** Presence of this variable indicates that the debug symbols should be stripped. */
  STRIP_DEBUG_SYMBOLS("strip_debug_symbols"),
  /** Truthy when current action is a cc_test linking action, falsey otherwise. */
  IS_CC_TEST("is_cc_test"),
  /**
   * Presence of this variable indicates that files were compiled with fission (debug info is in
   * .dwo files instead of .o files and linker needs to know).
   */
  IS_USING_FISSION("is_using_fission"),
  /** Path to the fdo instrument. */
  FDO_INSTRUMENT_PATH("fdo_instrument_path"),
  /** Path to the context sensitive fdo instrument. */
  CS_FDO_INSTRUMENT_PATH("cs_fdo_instrument_path"),
  /** Path to the Propeller Optimize linker profile artifact */
  PROPELLER_OPTIMIZE_LD_PATH("propeller_optimize_ld_path"),
  /** The name of the runtime solib symlink of the shared library. */
  RUNTIME_SOLIB_NAME("runtime_solib_name");

  private final String variableName;

  LinkBuildVariables(String variableName) {
    this.variableName = variableName;
  }

  public String getVariableName() {
    return variableName;
  }

  public static CcToolchainVariables setupVariables(
      StarlarkThread thread,
      boolean isUsingLinkerNotArchiver,
      PathFragment binDirectoryPath,
      String outputFile,
      String runtimeSolibName,
      boolean isCreatingSharedLibrary,
      String paramFile,
      String thinltoParamFile,
      String thinltoMergedObjectFile,
      boolean mustKeepDebug,
      CcToolchainProvider ccToolchainProvider,
      CppConfiguration cppConfiguration,
      BuildOptions buildOptions,
      FeatureConfiguration featureConfiguration,
      boolean useTestOnlyFlags,
      boolean isLtoIndexing,
      Iterable<String> userLinkFlags,
      String interfaceLibraryBuilder,
      String interfaceLibraryOutput,
      PathFragment ltoOutputRootPrefix,
      PathFragment ltoObjRootPrefix,
      String defFile,
      FdoContext fdoContext,
      NestedSet<String> runtimeLibrarySearchDirectories,
      SequenceBuilder librariesToLink,
      NestedSet<String> librarySearchDirectories,
      boolean addIfsoRelatedVariables)
      throws EvalException, InterruptedException {
    CcToolchainVariables.Builder buildVariables =
        CcToolchainVariables.builder(
            CcToolchainProvider.getBuildVars(
                ccToolchainProvider,
                thread,
                cppConfiguration,
                buildOptions,
                buildOptions.get(CoreOptions.class).cpu,
                ccToolchainProvider.getBuildVarsFunc()));

    // pic
    if (cppConfiguration.forcePic()) {
      buildVariables.addStringVariable(FORCE_PIC.getVariableName(), "");
    }

    if (!mustKeepDebug && cppConfiguration.shouldStripBinaries()) {
      buildVariables.addStringVariable(STRIP_DEBUG_SYMBOLS.getVariableName(), "");
    }

    if (isUsingLinkerNotArchiver
        && CcToolchainProvider.shouldCreatePerObjectDebugInfo(
            featureConfiguration, cppConfiguration)) {
      buildVariables.addStringVariable(IS_USING_FISSION.getVariableName(), "");
    }

    if (!cppConfiguration.useCcTestFeature()) {
      buildVariables.addBooleanValue(IS_CC_TEST.getVariableName(), useTestOnlyFlags);
    }

    if (runtimeLibrarySearchDirectories != null) {
      buildVariables.addStringSequenceVariable(
          RUNTIME_LIBRARY_SEARCH_DIRECTORIES.getVariableName(), runtimeLibrarySearchDirectories);
    }

    if (librariesToLink != null) {
      buildVariables.addCustomBuiltVariable(LIBRARIES_TO_LINK.getVariableName(), librariesToLink);
    }

    buildVariables.addStringSequenceVariable(
        LIBRARY_SEARCH_DIRECTORIES.getVariableName(), librarySearchDirectories);

    if (paramFile != null) {
      buildVariables.addStringVariable(LINKER_PARAM_FILE.getVariableName(), paramFile);
    }

    // output exec path
    if (outputFile != null && !isLtoIndexing) {
      buildVariables.addStringVariable(OUTPUT_EXECPATH.getVariableName(), outputFile);
    }

    if (runtimeSolibName != null && !isLtoIndexing) {
      buildVariables.addStringVariable(RUNTIME_SOLIB_NAME.getVariableName(), runtimeSolibName);
    }

    if (isLtoIndexing) {
      if (thinltoParamFile != null) {
        // This is a lto-indexing action and we want it to populate param file.
        buildVariables.addStringVariable(
            THINLTO_INDEXING_PARAM_FILE.getVariableName(), thinltoParamFile);
        // TODO(b/33846234): Remove once all the relevant crosstools don't depend on the variable.
        buildVariables.addStringVariable("thinlto_optional_params_file", "=" + thinltoParamFile);
      } else {
        buildVariables.addStringVariable(THINLTO_INDEXING_PARAM_FILE.getVariableName(), "");
        // TODO(b/33846234): Remove once all the relevant crosstools don't depend on the variable.
        buildVariables.addStringVariable("thinlto_optional_params_file", "");
      }
      // Given "fullbitcode_prefix;thinlto_index_prefix;native_object_prefix", replaces
      // fullbitcode_prefix with thinlto_index_prefix to generate the index and imports files.
      // fullbitcode_prefix is the empty string because we are appending a prefix to the fullbitcode
      // instead of replacing it. This argument is passed to the linker.
      // The native objects generated after the LTOBackend action are stored in a directory by
      // replacing the prefix "fullbitcode_prefix" with "native_object_prefix", and this is used
      // when generating the param file in the indexing step, which will be used during the final
      // link step.
      if (!ltoOutputRootPrefix.equals(ltoObjRootPrefix)) {
        buildVariables.addStringVariable(
            THINLTO_PREFIX_REPLACE.getVariableName(),
            ";"
                + binDirectoryPath.getRelative(ltoOutputRootPrefix)
                + "/;"
                + binDirectoryPath.getRelative(ltoObjRootPrefix)
                + "/");
      } else {
        buildVariables.addStringVariable(
            THINLTO_PREFIX_REPLACE.getVariableName(),
            ";" + binDirectoryPath.getRelative(ltoOutputRootPrefix) + "/");
      }
      String objectFileExtension =
          ccToolchainProvider
              .getFeatures()
              .getArtifactNameExtensionForCategory(ArtifactCategory.OBJECT_FILE);
      if (!featureConfiguration.isEnabled(CppRuleClasses.NO_USE_LTO_INDEXING_BITCODE_FILE)) {
        buildVariables.addStringVariable(
            THINLTO_OBJECT_SUFFIX_REPLACE.getVariableName(),
            Iterables.getOnlyElement(CppFileTypes.LTO_INDEXING_OBJECT_FILE.getExtensions())
                + ";"
                + objectFileExtension);
      }
      if (thinltoMergedObjectFile != null) {
        buildVariables.addStringVariable(
            THINLTO_MERGED_OBJECT_FILE.getVariableName(), thinltoMergedObjectFile);
      }
    } else {
      if (thinltoParamFile != null) {
        // This is a normal link action and we need to use param file created by lto-indexing.
        buildVariables.addStringVariable(THINLTO_PARAM_FILE.getVariableName(), thinltoParamFile);
      }
    }

    if (addIfsoRelatedVariables) {
      boolean shouldGenerateInterfaceLibrary =
          outputFile != null
              && interfaceLibraryBuilder != null
              && interfaceLibraryOutput != null
              && !isLtoIndexing;
      buildVariables.addStringVariable(
          GENERATE_INTERFACE_LIBRARY.getVariableName(),
          shouldGenerateInterfaceLibrary ? "yes" : "no");
      buildVariables.addStringVariable(
          INTERFACE_LIBRARY_BUILDER.getVariableName(),
          shouldGenerateInterfaceLibrary ? interfaceLibraryBuilder : "ignored");
      buildVariables.addStringVariable(
          INTERFACE_LIBRARY_INPUT.getVariableName(),
          shouldGenerateInterfaceLibrary ? outputFile : "ignored");
      buildVariables.addStringVariable(
          INTERFACE_LIBRARY_OUTPUT.getVariableName(),
          shouldGenerateInterfaceLibrary ? interfaceLibraryOutput : "ignored");
    }

    if (defFile != null) {
      buildVariables.addStringVariable(DEF_FILE_PATH.getVariableName(), defFile);
    }

    if (featureConfiguration.isEnabled(CppRuleClasses.FDO_INSTRUMENT)) {
      Preconditions.checkArgument(fdoContext.getBranchFdoProfile() == null);
      String fdoInstrument = cppConfiguration.getFdoInstrument();
      Preconditions.checkNotNull(fdoInstrument);
      buildVariables.addStringVariable(FDO_INSTRUMENT_PATH.getVariableName(), fdoInstrument);
    } else if (featureConfiguration.isEnabled(CppRuleClasses.CS_FDO_INSTRUMENT)) {
      String csFdoInstrument = ccToolchainProvider.getCSFdoInstrument();
      Preconditions.checkNotNull(csFdoInstrument);
      buildVariables.addStringVariable(CS_FDO_INSTRUMENT_PATH.getVariableName(), csFdoInstrument);
    }

    if (!isLtoIndexing
        && !ccToolchainProvider.isToolConfiguration()
        && fdoContext != null
        && featureConfiguration.isEnabled(CppRuleClasses.PROPELLER_OPTIMIZE)
        && fdoContext.getPropellerOptimizeInputFile() != null
        && fdoContext.getPropellerOptimizeInputFile().getLdArtifact() != null) {
      buildVariables.addStringVariable(
          PROPELLER_OPTIMIZE_LD_PATH.getVariableName(),
          fdoContext.getPropellerOptimizeInputFile().getLdArtifact().getExecPathString());
    }
    Iterable<String> userLinkFlagsWithLtoIndexingIfNeeded;
    if (!isLtoIndexing || cppConfiguration.useStandaloneLtoIndexingCommandLines()) {
      userLinkFlagsWithLtoIndexingIfNeeded = userLinkFlags;
    } else {
      ImmutableList.Builder<String> opts = ImmutableList.builder();
      opts.addAll(userLinkFlags);
      opts.addAll(
          featureConfiguration.getCommandLine(
              CppActionNames.LTO_INDEXING, buildVariables.build(), /* expander= */ null));
      opts.addAll(cppConfiguration.getLtoIndexOptions());
      userLinkFlagsWithLtoIndexingIfNeeded = opts.build();
    }

    // For now, silently ignore linkopts if this is a static library
    userLinkFlagsWithLtoIndexingIfNeeded =
        isUsingLinkerNotArchiver ? userLinkFlagsWithLtoIndexingIfNeeded : ImmutableList.of();

    buildVariables.addStringSequenceVariable(
        LinkBuildVariables.USER_LINK_FLAGS.getVariableName(),
        removePieIfCreatingSharedLibrary(
            isCreatingSharedLibrary, userLinkFlagsWithLtoIndexingIfNeeded));
    return buildVariables.build();
  }

  private static Iterable<String> removePieIfCreatingSharedLibrary(
      boolean isCreatingSharedLibrary, Iterable<String> flags) {
    if (isCreatingSharedLibrary) {
      return Iterables.filter(
          flags,
          Predicates.not(
              Predicates.or(Predicates.equalTo("-pie"), Predicates.equalTo("-Wl,-pie"))));
    } else {
      return flags;
    }
  }
}
