// Copyright 2017 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.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.rules.cpp.CppActionConfigs.CppPlatform;
import com.google.devtools.build.lib.rules.cpp.Link.LinkingMode;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain.ArtifactNamePattern;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath;
import com.google.protobuf.Descriptors.FieldDescriptor;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * Information describing the C++ compiler derived from the CToolchain proto.
 *
 * <p>This wrapper class is used to re-plumb information so that it's eventually accessed through
 * {@link CcToolchainProvider} instead of {@link CppConfiguration}.
 */
@AutoCodec
@Immutable
public final class CppToolchainInfo {
  private final String toolchainIdentifier;
  private final CcToolchainFeatures toolchainFeatures;

  private final ImmutableMap<String, PathFragment> toolPaths;
  private final String compiler;
  private final String abiGlibcVersion;

  private final String targetCpu;
  private final String targetOS;

  private final ImmutableList<String> rawBuiltInIncludeDirectories;
  private final PathFragment defaultSysroot;
  private final PathFragment runtimeSysroot;

  private final String targetLibc;
  private final String hostSystemName;
  private final ImmutableList<String> dynamicLibraryLinkFlags;
  private final ImmutableList<String> legacyLinkOptions;
  private final ImmutableListMultimap<LinkingMode, String> legacyLinkOptionsFromLinkingMode;
  private final ImmutableListMultimap<CompilationMode, String> legacyLinkOptionsFromCompilationMode;
  private final ImmutableList<String> testOnlyLinkFlags;
  private final ImmutableList<String> ldOptionsForEmbedding;
  private final ImmutableList<String> objCopyOptionsForEmbedding;

  private final Label ccToolchainLabel;
  private final Label staticRuntimeLibsLabel;
  private final Label dynamicRuntimeLibsLabel;
  private final String solibDirectory;
  private final String abi;
  private final String targetSystemName;

  private final ImmutableMap<String, String> additionalMakeVariables;
  // TODO(b/65151735): Remove when cc_flags is entirely from features.
  private final String legacyCcFlagsMakeVariable;

  private final ImmutableList<String> crosstoolCompilerFlags;
  private final ImmutableList<String> crosstoolCxxFlags;

  private final ImmutableListMultimap<CompilationMode, String> cFlagsByCompilationMode;
  private final ImmutableListMultimap<CompilationMode, String> cxxFlagsByCompilationMode;

  private final ImmutableList<String> unfilteredCompilerFlags;

  private final boolean supportsFission;
  private final boolean supportsStartEndLib;
  private final boolean supportsEmbeddedRuntimes;
  private final boolean supportsDynamicLinker;
  private final boolean supportsInterfaceSharedLibraries;
  private final boolean toolchainNeedsPic;

  /**
   * Creates a CppToolchainInfo from CROSSTOOL info encapsulated in {@link CcToolchainConfigInfo}.
   */
  public static CppToolchainInfo create(
      Label toolchainLabel,
      CcToolchainConfigInfo ccToolchainConfigInfo,
      boolean disableLegacyCrosstoolFields,
      boolean disableGenruleCcToolchainDependency)
      throws EvalException {
    ImmutableMap<String, PathFragment> toolPaths =
        computeToolPaths(ccToolchainConfigInfo, getToolsDirectory(toolchainLabel));
    PathFragment defaultSysroot =
        CppConfiguration.computeDefaultSysroot(ccToolchainConfigInfo.getBuiltinSysroot());

    ImmutableListMultimap.Builder<LinkingMode, String> linkOptionsFromLinkingModeBuilder =
        ImmutableListMultimap.builder();

    boolean haveDynamicMode = false;
    if (!disableLegacyCrosstoolFields) {
      // If a toolchain supports dynamic libraries at all, there must be at least one
      // of the following:
      // - a "DYNAMIC" section in linking_mode_flags (even if no flags are needed)
      // - a non-empty list in one of the dynamicLibraryLinkerFlag fields
      // If none of the above contain data, then the toolchain can't do dynamic linking.
      haveDynamicMode = ccToolchainConfigInfo.hasDynamicLinkingModeFlags();
      linkOptionsFromLinkingModeBuilder.putAll(
          LinkingMode.DYNAMIC, ccToolchainConfigInfo.getDynamicLinkingModeFlags());
      linkOptionsFromLinkingModeBuilder.putAll(
          LinkingMode.LEGACY_FULLY_STATIC, ccToolchainConfigInfo.getFullyStaticLinkingModeFlags());
      linkOptionsFromLinkingModeBuilder.putAll(
          LinkingMode.STATIC, ccToolchainConfigInfo.getMostlyStaticLinkingModeFlags());
      linkOptionsFromLinkingModeBuilder.putAll(
          LinkingMode.LEGACY_MOSTLY_STATIC_LIBRARIES,
          ccToolchainConfigInfo.getMostlyStaticLibrariesLinkingModeFlags());
    }

    ImmutableListMultimap.Builder<CompilationMode, String> cFlagsBuilder =
        ImmutableListMultimap.builder();
    ImmutableListMultimap.Builder<CompilationMode, String> cxxFlagsBuilder =
        ImmutableListMultimap.builder();
    ImmutableListMultimap.Builder<CompilationMode, String> linkOptionsFromCompilationModeBuilder =
        ImmutableListMultimap.builder();

    if (!disableLegacyCrosstoolFields) {
      cFlagsBuilder.putAll(
          importCompilationMode(CrosstoolConfig.CompilationMode.OPT),
          ccToolchainConfigInfo.getOptCompilationModeCompilerFlags());
      cxxFlagsBuilder.putAll(
          importCompilationMode(CrosstoolConfig.CompilationMode.OPT),
          ccToolchainConfigInfo.getOptCompilationModeCxxFlags());
      linkOptionsFromCompilationModeBuilder.putAll(
          importCompilationMode(CrosstoolConfig.CompilationMode.OPT),
          ccToolchainConfigInfo.getOptCompilationModeLinkerFlags());
      cFlagsBuilder.putAll(
          importCompilationMode(CrosstoolConfig.CompilationMode.DBG),
          ccToolchainConfigInfo.getDbgCompilationModeCompilerFlags());
      cxxFlagsBuilder.putAll(
          importCompilationMode(CrosstoolConfig.CompilationMode.DBG),
          ccToolchainConfigInfo.getDbgCompilationModeCxxFlags());
      linkOptionsFromCompilationModeBuilder.putAll(
          importCompilationMode(CrosstoolConfig.CompilationMode.DBG),
          ccToolchainConfigInfo.getDbgCompilationModeLinkerFlags());
      cFlagsBuilder.putAll(
          importCompilationMode(CrosstoolConfig.CompilationMode.FASTBUILD),
          ccToolchainConfigInfo.getFastbuildCompilationModeCompilerFlags());
      cxxFlagsBuilder.putAll(
          importCompilationMode(CrosstoolConfig.CompilationMode.FASTBUILD),
          ccToolchainConfigInfo.getFastbuildCompilationModeCxxFlags());
      linkOptionsFromCompilationModeBuilder.putAll(
          importCompilationMode(CrosstoolConfig.CompilationMode.FASTBUILD),
          ccToolchainConfigInfo.getFastbuildCompilationModeLinkerFlags());
    }

    try {
      return new CppToolchainInfo(
          ccToolchainConfigInfo.getToolchainIdentifier(),
          new CcToolchainFeatures(ccToolchainConfigInfo, getToolsDirectory(toolchainLabel)),
          toolPaths,
          ccToolchainConfigInfo.getCompiler(),
          ccToolchainConfigInfo.getAbiLibcVersion(),
          ccToolchainConfigInfo.getTargetCpu(),
          ccToolchainConfigInfo.getCcTargetOs(),
          ccToolchainConfigInfo.getCxxBuiltinIncludeDirectories(),
          defaultSysroot,
          // The runtime sysroot should really be set from --grte_top. However, currently libc has
          // no way to set the sysroot. The CROSSTOOL file does set the runtime sysroot, in the
          // builtin_sysroot field. This implies that you can not arbitrarily mix and match
          // Crosstool and libc versions, you must always choose compatible ones.
          defaultSysroot,
          ccToolchainConfigInfo.getTargetLibc(),
          ccToolchainConfigInfo.getHostSystemName(),
          disableLegacyCrosstoolFields
              ? ImmutableList.of()
              : ccToolchainConfigInfo.getDynamicLibraryLinkerFlags(),
          disableLegacyCrosstoolFields
              ? ImmutableList.of()
              : ccToolchainConfigInfo.getLinkerFlags(),
          linkOptionsFromLinkingModeBuilder.build(),
          linkOptionsFromCompilationModeBuilder.build(),
          disableLegacyCrosstoolFields
              ? ImmutableList.of()
              : ccToolchainConfigInfo.getTestOnlyLinkerFlags(),
          disableLegacyCrosstoolFields
              ? ImmutableList.of()
              : ccToolchainConfigInfo.getLdEmbedFlags(),
          disableLegacyCrosstoolFields
              ? ImmutableList.of()
              : ccToolchainConfigInfo.getObjcopyEmbedFlags(),
          toolchainLabel,
          disableLegacyCrosstoolFields
              ? null
              : toolchainLabel.getRelativeWithRemapping(
                  !ccToolchainConfigInfo.getStaticRuntimesFilegroup().isEmpty()
                      ? ccToolchainConfigInfo.getStaticRuntimesFilegroup()
                      : "static-runtime-libs-" + ccToolchainConfigInfo.getTargetCpu(),
                  ImmutableMap.of()),
          disableLegacyCrosstoolFields
              ? null
              : toolchainLabel.getRelativeWithRemapping(
                  !ccToolchainConfigInfo.getDynamicRuntimesFilegroup().isEmpty()
                      ? ccToolchainConfigInfo.getDynamicRuntimesFilegroup()
                      : "dynamic-runtime-libs-" + ccToolchainConfigInfo.getTargetCpu(),
                  ImmutableMap.of()),
          "_solib_" + ccToolchainConfigInfo.getTargetCpu(),
          ccToolchainConfigInfo.getAbiVersion(),
          ccToolchainConfigInfo.getTargetSystemName(),
          computeAdditionalMakeVariables(
              ccToolchainConfigInfo, disableGenruleCcToolchainDependency),
          computeLegacyCcFlagsMakeVariable(ccToolchainConfigInfo),
          disableLegacyCrosstoolFields
              ? ImmutableList.of()
              : ccToolchainConfigInfo.getCompilerFlags(),
          disableLegacyCrosstoolFields ? ImmutableList.of() : ccToolchainConfigInfo.getCxxFlags(),
          cFlagsBuilder.build(),
          cxxFlagsBuilder.build(),
          disableLegacyCrosstoolFields
              ? ImmutableList.of()
              : ccToolchainConfigInfo.getUnfilteredCxxFlags(),
          disableLegacyCrosstoolFields ? false : ccToolchainConfigInfo.supportsFission(),
          disableLegacyCrosstoolFields ? false : ccToolchainConfigInfo.supportsStartEndLib(),
          disableLegacyCrosstoolFields ? false : ccToolchainConfigInfo.supportsEmbeddedRuntimes(),
          disableLegacyCrosstoolFields
              ? false
              : haveDynamicMode || !ccToolchainConfigInfo.getDynamicLibraryLinkerFlags().isEmpty(),
          disableLegacyCrosstoolFields
              ? false
              : ccToolchainConfigInfo.supportsInterfaceSharedLibraries(),
          disableLegacyCrosstoolFields ? false : ccToolchainConfigInfo.needsPic());
    } catch (LabelSyntaxException e) {
      // All of the above label.getRelativeWithRemapping() calls are valid labels, and the
      // crosstool_top was already checked earlier in the process.
      throw new EvalException(Location.BUILTIN, e);
    }
  }

  @AutoCodec.Instantiator
  CppToolchainInfo(
      String toolchainIdentifier,
      CcToolchainFeatures toolchainFeatures,
      ImmutableMap<String, PathFragment> toolPaths,
      String compiler,
      String abiGlibcVersion,
      String targetCpu,
      String targetOS,
      ImmutableList<String> rawBuiltInIncludeDirectories,
      PathFragment defaultSysroot,
      PathFragment runtimeSysroot,
      String targetLibc,
      String hostSystemName,
      ImmutableList<String> dynamicLibraryLinkFlags,
      ImmutableList<String> legacyLinkOptions,
      ImmutableListMultimap<LinkingMode, String> legacyLinkOptionsFromLinkingMode,
      ImmutableListMultimap<CompilationMode, String> legacyLinkOptionsFromCompilationMode,
      ImmutableList<String> testOnlyLinkFlags,
      ImmutableList<String> ldOptionsForEmbedding,
      ImmutableList<String> objCopyOptionsForEmbedding,
      Label ccToolchainLabel,
      Label staticRuntimeLibsLabel,
      Label dynamicRuntimeLibsLabel,
      String solibDirectory,
      String abi,
      String targetSystemName,
      ImmutableMap<String, String> additionalMakeVariables,
      String legacyCcFlagsMakeVariable,
      ImmutableList<String> crosstoolCompilerFlags,
      ImmutableList<String> crosstoolCxxFlags,
      ImmutableListMultimap<CompilationMode, String> cFlagsByCompilationMode,
      ImmutableListMultimap<CompilationMode, String> cxxFlagsByCompilationMode,
      ImmutableList<String> unfilteredCompilerFlags,
      boolean supportsFission,
      boolean supportsStartEndLib,
      boolean supportsEmbeddedRuntimes,
      boolean supportsDynamicLinker,
      boolean supportsInterfaceSharedLibraries,
      boolean toolchainNeedsPic)
      throws EvalException {
    this.toolchainIdentifier = toolchainIdentifier;
    // Since this field can be derived from `crosstoolInfo`, it is re-derived instead of serialized.
    this.toolchainFeatures = toolchainFeatures;
    this.toolPaths = toolPaths;
    this.compiler = compiler;
    this.abiGlibcVersion = abiGlibcVersion;
    this.targetCpu = targetCpu;
    this.targetOS = targetOS;
    this.rawBuiltInIncludeDirectories = rawBuiltInIncludeDirectories;
    this.defaultSysroot = defaultSysroot;
    this.runtimeSysroot = runtimeSysroot;
    this.targetLibc = targetLibc;
    this.hostSystemName = hostSystemName;
    this.dynamicLibraryLinkFlags = dynamicLibraryLinkFlags;
    this.legacyLinkOptions = legacyLinkOptions;
    this.legacyLinkOptionsFromLinkingMode = legacyLinkOptionsFromLinkingMode;
    this.legacyLinkOptionsFromCompilationMode = legacyLinkOptionsFromCompilationMode;
    this.testOnlyLinkFlags = testOnlyLinkFlags;
    this.ldOptionsForEmbedding = ldOptionsForEmbedding;
    this.objCopyOptionsForEmbedding = objCopyOptionsForEmbedding;
    this.ccToolchainLabel = ccToolchainLabel;
    this.staticRuntimeLibsLabel = staticRuntimeLibsLabel;
    this.dynamicRuntimeLibsLabel = dynamicRuntimeLibsLabel;
    this.solibDirectory = solibDirectory;
    this.abi = abi;
    this.targetSystemName = targetSystemName;
    this.additionalMakeVariables = additionalMakeVariables;
    this.legacyCcFlagsMakeVariable = legacyCcFlagsMakeVariable;
    this.crosstoolCompilerFlags = crosstoolCompilerFlags;
    this.crosstoolCxxFlags = crosstoolCxxFlags;
    this.cFlagsByCompilationMode = cFlagsByCompilationMode;
    this.cxxFlagsByCompilationMode = cxxFlagsByCompilationMode;
    this.unfilteredCompilerFlags = unfilteredCompilerFlags;
    this.supportsFission = supportsFission;
    this.supportsStartEndLib = supportsStartEndLib;
    this.supportsEmbeddedRuntimes = supportsEmbeddedRuntimes;
    this.supportsDynamicLinker = supportsDynamicLinker;
    this.supportsInterfaceSharedLibraries = supportsInterfaceSharedLibraries;
    this.toolchainNeedsPic = toolchainNeedsPic;
  }

  @VisibleForTesting
  static CompilationMode importCompilationMode(CrosstoolConfig.CompilationMode mode) {
    return CompilationMode.valueOf(mode.name());
  }

  // TODO(bazel-team): Remove this once bazel supports all crosstool flags through
  // feature configuration, and all crosstools have been converted.
  public static CToolchain addLegacyFeatures(
      CToolchain toolchain, PathFragment crosstoolTopPathFragment) {
    CToolchain.Builder toolchainBuilder = CToolchain.newBuilder();

    Set<ArtifactCategory> definedCategories = new HashSet<>();
    for (ArtifactNamePattern pattern : toolchainBuilder.getArtifactNamePatternList()) {
      try {
        definedCategories.add(
            ArtifactCategory.valueOf(pattern.getCategoryName().toUpperCase(Locale.ENGLISH)));
      } catch (IllegalArgumentException e) {
        // Invalid category name, will be detected later.
        continue;
      }
    }

    for (ArtifactCategory category : ArtifactCategory.values()) {
      if (!definedCategories.contains(category) && category.getDefaultPrefix() != null
          && category.getDefaultExtension() != null) {
        toolchainBuilder.addArtifactNamePattern(
            ArtifactNamePattern.newBuilder()
                .setCategoryName(category.toString().toLowerCase())
                .setPrefix(category.getDefaultPrefix())
                .setExtension(category.getDefaultExtension())
                .build());
      }
    }

    ImmutableSet<String> featureNames =
        toolchain
            .getFeatureList()
            .stream()
            .map(feature -> feature.getName())
            .collect(ImmutableSet.toImmutableSet());
    if (!featureNames.contains(CppRuleClasses.NO_LEGACY_FEATURES)) {
        String gccToolPath = "DUMMY_GCC_TOOL";
        String linkerToolPath = "DUMMY_LINKER_TOOL";
        String arToolPath = "DUMMY_AR_TOOL";
        String stripToolPath = "DUMMY_STRIP_TOOL";
        for (ToolPath tool : toolchain.getToolPathList()) {
          if (tool.getName().equals(CppConfiguration.Tool.GCC.getNamePart())) {
            gccToolPath = tool.getPath();
            linkerToolPath =
                crosstoolTopPathFragment
                    .getRelative(PathFragment.create(tool.getPath()))
                    .getPathString();
          }
          if (tool.getName().equals(CppConfiguration.Tool.AR.getNamePart())) {
            arToolPath = tool.getPath();
          }
          if (tool.getName().equals(CppConfiguration.Tool.STRIP.getNamePart())) {
            stripToolPath = tool.getPath();
          }
        }

      // TODO(b/30109612): Remove fragile legacyCompileFlags shuffle once there are no legacy
      // crosstools.
      // Existing projects depend on flags from legacy toolchain fields appearing first on the
      // compile command line. 'legacy_compile_flags' feature contains all these flags, and so it
      // needs to appear before other features from {@link CppActionConfigs}.
      if (featureNames.contains(CppRuleClasses.LEGACY_COMPILE_FLAGS)) {
        CToolchain.Feature legacyCompileFlags =
            toolchain.getFeatureList().stream()
                .filter(feature -> feature.getName().equals(CppRuleClasses.LEGACY_COMPILE_FLAGS))
                .findFirst()
                .get();
        if (legacyCompileFlags != null) {
          toolchainBuilder.addFeature(legacyCompileFlags);
        }
      }
      if (featureNames.contains(CppRuleClasses.DEFAULT_COMPILE_FLAGS)) {
        CToolchain.Feature defaultCompileFlags =
            toolchain.getFeatureList().stream()
                .filter(feature -> feature.getName().equals(CppRuleClasses.DEFAULT_COMPILE_FLAGS))
                .findFirst()
                .get();
        if (defaultCompileFlags != null) {
          toolchainBuilder.addFeature(defaultCompileFlags);
        }
      }
      toolchain = removeSpecialFeatureFromToolchain(toolchain);

      CppPlatform platform =
          toolchain.getTargetLibc().equals(CppActionConfigs.MACOS_TARGET_LIBC)
              ? CppPlatform.MAC
              : CppPlatform.LINUX;

      toolchainBuilder.addAllActionConfig(
          CppActionConfigs.getLegacyActionConfigs(
              platform,
              gccToolPath,
              arToolPath,
              stripToolPath,
              toolchain.getSupportsInterfaceSharedObjects()));

      toolchainBuilder.addAllFeature(
          CppActionConfigs.getLegacyFeatures(
              platform,
              featureNames,
              linkerToolPath,
              toolchain.getSupportsEmbeddedRuntimes(),
              toolchain.getSupportsInterfaceSharedObjects()));
    }

    toolchainBuilder.mergeFrom(toolchain);

    if (!featureNames.contains(CppRuleClasses.NO_LEGACY_FEATURES)) {
      toolchainBuilder.addAllFeature(
          CppActionConfigs.getFeaturesToAppearLastInFeaturesList(featureNames));
    }

    return toolchainBuilder.build();
  }

  private static CToolchain removeSpecialFeatureFromToolchain(CToolchain toolchain) {
    FieldDescriptor featuresFieldDescriptor = CToolchain.getDescriptor().findFieldByName("feature");
    return toolchain
        .toBuilder()
        .setField(
            featuresFieldDescriptor,
            toolchain.getFeatureList().stream()
                .filter(feature -> !feature.getName().equals(CppRuleClasses.LEGACY_COMPILE_FLAGS))
                .filter(feature -> !feature.getName().equals(CppRuleClasses.DEFAULT_COMPILE_FLAGS))
                .collect(ImmutableList.toImmutableList()))
        .build();
  }

  /** @see CcToolchainProvider#getLegacyLinkOptions(). */
  public ImmutableList<String> getLegacyLinkOptions() {
    return legacyLinkOptions;
  }

  /** @see CcToolchainProvider#configureAllLegacyLinkOptions(CompilationMode, LinkingMode). */
  ImmutableList<String> configureAllLegacyLinkOptions(
      CompilationMode compilationMode, LinkingMode linkingMode) {
    List<String> result = new ArrayList<>();
    result.addAll(legacyLinkOptions);

    result.addAll(legacyLinkOptionsFromCompilationMode.get(compilationMode));
    result.addAll(legacyLinkOptionsFromLinkingMode.get(linkingMode));
    return ImmutableList.copyOf(result);
  }

  /**
   * Returns the toolchain identifier, which uniquely identifies the compiler version, target libc
   * version, and target cpu.
   */
  public String getToolchainIdentifier() {
    return toolchainIdentifier;
  }

  /** Returns the system name which is required by the toolchain to run. */
  public String getHostSystemName() {
    return hostSystemName;
  }

  @Override
  public String toString() {
    return toolchainIdentifier;
  }

  /** Returns the compiler version string (e.g. "gcc-4.1.1"). */
  public String getCompiler() {
    return compiler;
  }

  /** Returns the libc version string (e.g. "glibc-2.2.2"). */
  public String getTargetLibc() {
    return targetLibc;
  }

  /**
   * Returns the target architecture using blaze-specific constants (e.g. "piii").
   *
   * <p>Equivalent to {@link BuildConfiguration#getCpu()}
   */
  public String getTargetCpu() {
    return targetCpu;
  }

  /** Unused, for compatibility with things internal to Google. */
  public String getTargetOS() {
    return targetOS;
  }

  /**
   * Returns the path fragment that is either absolute or relative to the execution root that can be
   * used to execute the given tool.
   */
  public PathFragment getToolPathFragment(CppConfiguration.Tool tool) {
    return getToolPathFragment(toolPaths, tool);
  }

  /** Returns a label that references the current cc_toolchain target. */
  public Label getCcToolchainLabel() {
    return ccToolchainLabel;
  }

  /**
   * Returns a label that references the library files needed to statically link the C++ runtime
   * (i.e. libgcc.a, libgcc_eh.a, libstdc++.a) for the target architecture.
   */
  public Label getStaticRuntimeLibsLabel() {
    return staticRuntimeLibsLabel;
  }

  /**
   * Returns a label that references the library files needed to dynamically link the C++ runtime
   * (i.e. libgcc_s.so, libstdc++.so) for the target architecture.
   */
  public Label getDynamicRuntimeLibsLabel() {
    return dynamicRuntimeLibsLabel;
  }

  /**
   * Returns the abi we're using, which is a gcc version. E.g.: "gcc-3.4". Note that in practice we
   * might be using gcc-3.4 as ABI even when compiling with gcc-4.1.0, because ABIs are backwards
   * compatible.
   */
  // TODO(bazel-team): The javadoc should clarify how this is used in Blaze.
  public String getAbi() {
    return abi;
  }

  /**
   * Returns the glibc version used by the abi we're using. This is a glibc version number (e.g.,
   * "2.2.2"). Note that in practice we might be using glibc 2.2.2 as ABI even when compiling with
   * gcc-4.2.2, gcc-4.3.1, or gcc-4.4.0 (which use glibc 2.3.6), because ABIs are backwards
   * compatible.
   */
  // TODO(bazel-team): The javadoc should clarify how this is used in Blaze.
  public String getAbiGlibcVersion() {
    return abiGlibcVersion;
  }

  /**
   * Returns the configured features of the toolchain. Rules should not call this directly, but
   * instead use {@code CcToolchainProvider.getFeatures}.
   */
  public CcToolchainFeatures getFeatures() {
    return toolchainFeatures;
  }

  /** Returns whether the toolchain supports the --start-lib/--end-lib options. */
  public boolean supportsStartEndLib() {
    return supportsStartEndLib;
  }

  /** Returns whether the toolchain supports dynamic linking. */
  public boolean supportsDynamicLinker() {
    return supportsDynamicLinker;
  }

  /**
   * Returns whether this toolchain supports interface shared objects.
   *
   * <p>Should be true if this toolchain generates ELF objects.
   */
  public boolean supportsInterfaceSharedLibraries() {
    return supportsInterfaceSharedLibraries;
  }

  /**
   * Returns whether the toolchain supports linking C/C++ runtime libraries supplied inside the
   * toolchain distribution.
   */
  public boolean supportsEmbeddedRuntimes() {
    return supportsEmbeddedRuntimes;
  }

  /**
   * Returns whether the toolchain supports "Fission" C++ builds, i.e. builds where compilation
   * partitions object code and debug symbols into separate output files.
   */
  public boolean supportsFission() {
    return supportsFission;
  }

  /**
   * Returns whether shared libraries must be compiled with position independent code on this
   * platform.
   */
  public boolean toolchainNeedsPic() {
    return toolchainNeedsPic;
  }

  /**
   * Returns the run time sysroot, which is where the dynamic linker and system libraries are found
   * at runtime. This is usually an absolute path. If the toolchain compiler does not support
   * sysroots, then this method returns <code>null</code>.
   */
  public PathFragment getRuntimeSysroot() {
    return runtimeSysroot;
  }

  /**
   * Returns link options for the specified flag list, combined with universal options for all
   * shared libraries (regardless of link staticness).
   */
  ImmutableList<String> getSharedLibraryLinkOptions(ImmutableList<String> flags) {
    return ImmutableList.<String>builder().addAll(flags).addAll(dynamicLibraryLinkFlags).build();
  }

  /**
   * Returns test-only link options such that certain test-specific features can be configured
   * separately (e.g. lazy binding).
   */
  public ImmutableList<String> getTestOnlyLinkOptions() {
    return testOnlyLinkFlags;
  }

  /**
   * Returns the list of options to be used with 'objcopy' when converting binary files to object
   * files, or {@code null} if this operation is not supported.
   */
  public ImmutableList<String> getObjCopyOptionsForEmbedding() {
    return objCopyOptionsForEmbedding;
  }

  /**
   * Returns the list of options to be used with 'ld' when converting binary files to object files,
   * or {@code null} if this operation is not supported.
   */
  public ImmutableList<String> getLdOptionsForEmbedding() {
    return ldOptionsForEmbedding;
  }

  /**
   * Returns a map of additional make variables for use by {@link BuildConfiguration}. These are to
   * used to allow some build rules to avoid the limits on stack frame sizes and variable-length
   * arrays.
   *
   * <p>The returned map must contain an entry for {@code STACK_FRAME_UNLIMITED}, though the entry
   * may be an empty string.
   */
  public ImmutableMap<String, String> getAdditionalMakeVariables() {
    return additionalMakeVariables;
  }

  /**
   * Returns the legacy value of the CC_FLAGS Make variable.
   *
   * @deprecated Use the CC_FLAGS from feature configuration instead.
   */
  // TODO(b/65151735): Remove when cc_flags is entirely from features.
  @Deprecated
  public String getLegacyCcFlagsMakeVariable() {
    return legacyCcFlagsMakeVariable;
  }

  public final boolean isLLVMCompiler() {
    // TODO(tmsriram): Checking for "llvm" does not handle all the cases.  This
    // is temporary until the crosstool configuration is modified to add fields that
    // indicate which flavor of fdo is being used.
    return toolchainIdentifier.contains("llvm");
  }

  /**
   * Return the name of the directory (relative to the bin directory) that holds mangled links to
   * shared libraries. This name is always set to the '{@code _solib_<cpu_archictecture_name>}.
   */
  public String getSolibDirectory() {
    return solibDirectory;
  }

  /** Returns the architecture component of the GNU System Name */
  public String getGnuSystemArch() {
    if (targetSystemName.indexOf('-') == -1) {
      return targetSystemName;
    }
    return targetSystemName.substring(0, targetSystemName.indexOf('-'));
  }

  /** Returns the GNU System Name */
  public String getTargetGnuSystemName() {
    return targetSystemName;
  }

  public PathFragment getDefaultSysroot() {
    return defaultSysroot;
  }

  /** Returns built-in include directories. */
  public ImmutableList<String> getRawBuiltInIncludeDirectories() {
    return rawBuiltInIncludeDirectories;
  }

  /** Returns compiler flags for C/C++/Asm compilation. */
  public ImmutableList<String> getCompilerFlags() {
    return crosstoolCompilerFlags;
  }

  /** Returns additional compiler flags for C++ compilation. */
  public ImmutableList<String> getCxxFlags() {
    return crosstoolCxxFlags;
  }

  /** Returns compiler flags for C compilation by compilation mode. */
  public ImmutableListMultimap<CompilationMode, String> getCFlagsByCompilationMode() {
    return cFlagsByCompilationMode;
  }

  /** Returns compiler flags for C++ compilation, by compilation mode. */
  public ImmutableListMultimap<CompilationMode, String> getCxxFlagsByCompilationMode() {
    return cxxFlagsByCompilationMode;
  }

  /** Returns unfiltered compiler options for C++ from this toolchain. */
  public ImmutableList<String> getUnfilteredCompilerOptions(@Nullable PathFragment sysroot) {
    if (sysroot == null) {
      return unfilteredCompilerFlags;
    }
    return ImmutableList.<String>builder()
        .add("--sysroot=" + sysroot)
        .addAll(unfilteredCompilerFlags)
        .build();
  }

  private static ImmutableMap<String, String> computeAdditionalMakeVariables(
      CcToolchainConfigInfo ccToolchainConfigInfo, boolean disableGenruleCcToolchainDependency) {
    Map<String, String> makeVariablesBuilder = new HashMap<>();
    // The following are to be used to allow some build rules to avoid the limits on stack frame
    // sizes and variable-length arrays.
    // These variables are initialized here, but may be overridden by the getMakeVariables() checks.
    makeVariablesBuilder.put("STACK_FRAME_UNLIMITED", "");
    makeVariablesBuilder.put(CppConfiguration.CC_FLAGS_MAKE_VARIABLE_NAME, "");
    for (Pair<String, String> variable : ccToolchainConfigInfo.getMakeVariables()) {
      makeVariablesBuilder.put(variable.getFirst(), variable.getSecond());
    }

    if (disableGenruleCcToolchainDependency) {
      makeVariablesBuilder.remove(CppConfiguration.CC_FLAGS_MAKE_VARIABLE_NAME);
    }

    return ImmutableMap.copyOf(makeVariablesBuilder);
  }

  // TODO(b/65151735): Remove when cc_flags is entirely from features.
  private static String computeLegacyCcFlagsMakeVariable(
      CcToolchainConfigInfo ccToolchainConfigInfo) {
    String legacyCcFlags = "";
    // Needs to ensure the last value with the name is used, to match the previous logic in
    // computeAdditionalMakeVariables.
    for (Pair<String, String> variable : ccToolchainConfigInfo.getMakeVariables()) {
      if (variable.getFirst().equals(CppConfiguration.CC_FLAGS_MAKE_VARIABLE_NAME)) {
        legacyCcFlags = variable.getSecond();
      }
    }

    return legacyCcFlags;
  }

  private static ImmutableMap<String, PathFragment> computeToolPaths(
      CcToolchainConfigInfo ccToolchainConfigInfo, PathFragment crosstoolTopPathFragment)
      throws EvalException {
    Map<String, PathFragment> toolPathsCollector = Maps.newHashMap();
    for (Pair<String, String> tool : ccToolchainConfigInfo.getToolPaths()) {
      String pathStr = tool.getSecond();
      if (!PathFragment.isNormalized(pathStr)) {
        throw new IllegalArgumentException("The include path '" + pathStr + "' is not normalized.");
      }
      PathFragment path = PathFragment.create(pathStr);
      toolPathsCollector.put(tool.getFirst(), crosstoolTopPathFragment.getRelative(path));
    }

    if (toolPathsCollector.isEmpty()) {
      // If no paths are specified, we just use the names of the tools as the path.
      for (CppConfiguration.Tool tool : CppConfiguration.Tool.values()) {
        toolPathsCollector.put(
            tool.getNamePart(), crosstoolTopPathFragment.getRelative(tool.getNamePart()));
      }
    } else {
      Iterable<CppConfiguration.Tool> neededTools =
          Iterables.filter(
              EnumSet.allOf(CppConfiguration.Tool.class),
              tool -> {
                if (tool == CppConfiguration.Tool.DWP) {
                  // When fission is unsupported, don't check for the dwp tool.
                  return ccToolchainConfigInfo.supportsFission();
                } else if (tool == CppConfiguration.Tool.LLVM_PROFDATA) {
                  // TODO(tmsriram): Fix this to check if this is a llvm crosstool
                  // and return true.  This needs changes to crosstool_config.proto.
                  return false;
                } else if (tool == CppConfiguration.Tool.GCOVTOOL
                    || tool == CppConfiguration.Tool.OBJCOPY) {
                  // gcov-tool and objcopy are optional, don't check whether they're present
                  return false;
                } else {
                  return true;
                }
              });
      for (CppConfiguration.Tool tool : neededTools) {
        if (!toolPathsCollector.containsKey(tool.getNamePart())) {
          throw new EvalException(
              Location.BUILTIN, "Tool path for '" + tool.getNamePart() + "' is missing");
        }
      }
    }
    return ImmutableMap.copyOf(toolPathsCollector);
  }

  private static PathFragment getToolPathFragment(
      ImmutableMap<String, PathFragment> toolPaths, CppConfiguration.Tool tool) {
    return toolPaths.get(tool.getNamePart());
  }

  public PathFragment getToolsDirectory() {
    return getToolsDirectory(ccToolchainLabel);
  }

  static PathFragment getToolsDirectory(Label ccToolchainLabel) {
    return ccToolchainLabel.getPackageIdentifier().getPathUnderExecRoot();
  }
}
