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

/** 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.Builder setupLtoIndexingVariables(
      PathFragment binDirectoryPath,
      String thinltoParamFile,
      String thinltoMergedObjectFile,
      CcToolchainProvider ccToolchainProvider,
      FeatureConfiguration featureConfiguration,
      PathFragment ltoOutputRootPrefix,
      PathFragment ltoObjRootPrefix)
      throws EvalException {
    CcToolchainVariables.Builder buildVariables = CcToolchainVariables.builder();

    // 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);

    // 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);
    }

    buildVariables.addStringVariable(
        THINLTO_MERGED_OBJECT_FILE.getVariableName(), thinltoMergedObjectFile);

    buildVariables.addStringVariable(GENERATE_INTERFACE_LIBRARY.getVariableName(), "no");
    buildVariables.addStringVariable(INTERFACE_LIBRARY_BUILDER.getVariableName(), "ignored");
    buildVariables.addStringVariable(INTERFACE_LIBRARY_INPUT.getVariableName(), "ignored");
    buildVariables.addStringVariable(INTERFACE_LIBRARY_OUTPUT.getVariableName(), "ignored");
    return buildVariables;
  }

  public static CcToolchainVariables.Builder setupLinkingVariables(
      String outputFile,
      String runtimeSolibName,
      String thinltoParamFile,
      CcToolchainProvider ccToolchainProvider,
      FeatureConfiguration featureConfiguration,
      String interfaceLibraryBuilder,
      String interfaceLibraryOutput,
      FdoContext fdoContext)
      throws EvalException {
    CcToolchainVariables.Builder buildVariables = CcToolchainVariables.builder();
    if (thinltoParamFile != null) {
      // This is a normal link action and we need to use param file created by lto-indexing.
      buildVariables.addStringVariable(
          LinkBuildVariables.THINLTO_PARAM_FILE.getVariableName(), thinltoParamFile);
    }

    // output exec path
    buildVariables.addStringVariable(
        LinkBuildVariables.OUTPUT_EXECPATH.getVariableName(), outputFile);

    buildVariables.addStringVariable(
        LinkBuildVariables.RUNTIME_SOLIB_NAME.getVariableName(), runtimeSolibName);

    if (!ccToolchainProvider.isToolConfiguration()
        && fdoContext != null
        && featureConfiguration.isEnabled(CppRuleClasses.PROPELLER_OPTIMIZE)
        && fdoContext.getPropellerOptimizeInputFile() != null
        && fdoContext.getPropellerOptimizeInputFile().getLdArtifact() != null) {
      buildVariables.addStringVariable(
          LinkBuildVariables.PROPELLER_OPTIMIZE_LD_PATH.getVariableName(),
          fdoContext.getPropellerOptimizeInputFile().getLdArtifact().getExecPathString());
    }

    boolean shouldGenerateInterfaceLibrary =
        outputFile != null && interfaceLibraryBuilder != null && interfaceLibraryOutput != null;
    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");

    return buildVariables;
  }

  public static CcToolchainVariables.Builder setupCommonVariables(
      boolean isUsingLinkerNotArchiver,
      boolean isCreatingSharedLibrary,
      String paramFile,
      boolean mustKeepDebug,
      CcToolchainProvider ccToolchainProvider,
      FeatureConfiguration featureConfiguration,
      boolean useTestOnlyFlags,
      Iterable<String> userLinkFlags,
      FdoContext fdoContext,
      NestedSet<String> runtimeLibrarySearchDirectories,
      SequenceBuilder librariesToLink,
      NestedSet<String> librarySearchDirectories)
      throws EvalException {
    CcToolchainVariables.Builder buildVariables =
        CcToolchainVariables.builder(ccToolchainProvider.getBuildVars());
    CppConfiguration cppConfiguration = ccToolchainProvider.getCppConfiguration();

    // 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);
    }

    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);
    }

    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);
    }

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

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

  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;
    }
  }
}
