// 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.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.OutputGroupInfo;
import com.google.devtools.build.lib.analysis.PackageSpecificationProvider;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.Depset.TypeException;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.Info;
import com.google.devtools.build.lib.packages.Provider;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.packages.StarlarkInfo;
import com.google.devtools.build.lib.packages.StarlarkInfoWithSchema;
import com.google.devtools.build.lib.packages.StarlarkProviderWrapper;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
import com.google.devtools.build.lib.vfs.PathFragment;
import javax.annotation.Nullable;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import net.starlark.java.syntax.Location;

/** Information about a C++ compiler used by the <code>cc_*</code> rules. */
@Immutable
public final class CcToolchainProvider {

  public static final String STARLARK_NAME = "CcToolchainInfo";
  public static final CcToolchainInfoProvider PROVIDER = new CcToolchainInfoProvider();

  /** Provider class for {@link CcToolchainProvider} objects. */
  public static class CcToolchainInfoProvider extends StarlarkProviderWrapper<CcToolchainProvider>
      implements Provider {
    public CcToolchainInfoProvider() {
      super(
          Label.parseCanonicalUnchecked("@_builtins//:common/cc/cc_toolchain_info.bzl"),
          STARLARK_NAME);
    }

    public CcToolchainProvider wrapOrThrowEvalException(Info value) throws EvalException {
      if (value instanceof StarlarkInfoWithSchema
          && value.getProvider().getKey().equals(getKey())) {
        return new CcToolchainProvider((StarlarkInfo) value);
      } else {
        throw new EvalException(
            String.format("got value of type '%s', want 'CcToolchainInfo'", Starlark.type(value)));
      }
    }

    @Override
    public CcToolchainProvider wrap(Info value) throws RuleErrorException {
      if (value instanceof StarlarkInfoWithSchema
          && value.getProvider().getKey().equals(getKey())) {
        return new CcToolchainProvider((StarlarkInfo) value);
      } else {
        throw new RuleErrorException(
            "got value of type '" + Starlark.type(value) + "', want 'CcToolchainInfo'");
      }
    }

    @Override
    public boolean isExported() {
      return true;
    }

    @Override
    public String getPrintableName() {
      return STARLARK_NAME;
    }

    @Override
    public Location getLocation() {
      return Location.BUILTIN;
    }
  }

  @Nullable
  private static final NestedSet<Artifact> nullOrDepset(StarlarkInfo value, String key)
      throws EvalException, TypeException {
    if (value.getValue(key) == null || value.getValue(key) == Starlark.NONE) {
      return null;
    }
    return value.getValue(key, Depset.class).getSet(Artifact.class);
  }

  @Nullable
  private static final PathFragment nullOrPathFragment(StarlarkInfo value, String key)
      throws EvalException {
    if (value.getValue(key) == null || value.getValue(key) == Starlark.NONE) {
      return null;
    }
    return PathFragment.create(value.getValue(key, String.class));
  }

  private static final <T> T nullIfNone(StarlarkInfo value, String key, Class<T> type)
      throws EvalException {
    if (value.getValue(key) == null || value.getValue(key) == Starlark.NONE) {
      return null;
    }
    return value.getValue(key, type);
  }

  private static final ImmutableList<PathFragment> convertStarlarkListToPathFragments(
      StarlarkInfo value, String key) throws EvalException {
    ImmutableList.Builder<PathFragment> pathFragments = ImmutableList.builder();
    for (String pathString :
        Sequence.cast(value.getValue(key, Sequence.class), String.class, key)) {
      pathFragments.add(PathFragment.create(pathString));
    }
    return pathFragments.build();
  }

  private final StarlarkInfo value;

  private CcToolchainProvider(StarlarkInfo value) {
    this.value = value;
  }

  @VisibleForTesting
  public StarlarkInfo getValue() {
    return value;
  }

  public static CcToolchainProvider create(StarlarkInfo value) {
    return new CcToolchainProvider(value);
  }

  /**
   * Determines if we should apply -fPIC for this rule's C++ compilations. This determination is
   * generally made by the global C++ configuration settings "needsPic" and "usePicForBinaries".
   * However, an individual rule may override these settings by applying -fPIC" to its "nocopts"
   * attribute. This allows incompatible rules to "opt out" of global PIC settings (see bug:
   * "Provide a way to turn off -fPIC for targets that can't be built that way").
   *
   * @return true if this rule's compilations should apply -fPIC, false otherwise
   */
  public static boolean usePicForDynamicLibraries(
      CppConfiguration cppConfiguration, FeatureConfiguration featureConfiguration) {
    return cppConfiguration.forcePic()
        || featureConfiguration.isEnabled(CppRuleClasses.SUPPORTS_PIC);
  }

  /**
   * Returns true if PER_OBJECT_DEBUG_INFO are specified and supported by the CROSSTOOL for the
   * build implied by the given configuration, toolchain and feature configuration.
   */
  public static boolean shouldCreatePerObjectDebugInfo(
      FeatureConfiguration featureConfiguration, CppConfiguration cppConfiguration) {
    return cppConfiguration.fissionIsActiveForCurrentCompilationMode()
        && featureConfiguration.isEnabled(CppRuleClasses.PER_OBJECT_DEBUG_INFO);
  }

  /** Whether the toolchains supports header parsing. */
  public boolean supportsHeaderParsing() throws EvalException {
    return value.getValue("_supports_header_parsing", Boolean.class);
  }

  /**
   * Returns true if headers should be parsed in this build.
   *
   * <p>This means headers in 'srcs' and 'hdrs' will be "compiled" using {@link CppCompileAction}).
   * It will run compiler's parser to ensure the header is self-contained. This is required for
   * layering_check to work.
   */
  public static boolean shouldProcessHeaders(
      FeatureConfiguration featureConfiguration, CppConfiguration cppConfiguration) {
    return featureConfiguration.isEnabled(CppRuleClasses.PARSE_HEADERS);
  }

  /**
   * Returns the path String that is either absolute or relative to the execution root that can be
   * used to execute the given tool.
   *
   * @throws RuleErrorException when the tool is not specified by the toolchain.
   */
  public static String getToolPathString(
      ImmutableMap<String, String> toolPaths,
      CppConfiguration.Tool tool,
      Label ccToolchainLabel,
      String toolchainIdentifier)
      throws EvalException {
    String toolPath = getToolPathStringOrNull(toolPaths, tool);
    if (toolPath == null) {
      throw Starlark.errorf(
          "cc_toolchain '%s' with identifier '%s' doesn't define a tool path for '%s'",
          ccToolchainLabel, toolchainIdentifier, tool.getNamePart());
    }
    return toolPath;
  }

  /**
   * Returns the path string that is either absolute or relative to the execution root that can be
   * used to execute the given tool.
   */
  public static String getToolPathStringOrNull(ImmutableMap<String, String> toolPaths, Tool tool) {
    return toolPaths.get(tool.getNamePart());
  }

  public ImmutableMap<String, String> getToolPaths() throws EvalException {
    return ImmutableMap.copyOf(
        Dict.cast(
            value.getValue("_tool_paths", Dict.class), String.class, String.class, "_tool_paths"));
  }

  public ImmutableList<PathFragment> getBuiltInIncludeDirectories() throws EvalException {
    return convertStarlarkListToPathFragments(value, "built_in_include_directories");
  }

  /** Returns the identifier of the toolchain as specified in the {@code CToolchain} proto. */
  public String getToolchainIdentifier() throws EvalException {
    return value.getValue("toolchain_id", String.class);
  }

  /** Returns all the files in Crosstool. */
  public NestedSet<Artifact> getAllFiles() throws EvalException {
    try {
      return value.getValue("all_files", Depset.class).getSet(Artifact.class);
    } catch (TypeException e) {
      throw new EvalException(e);
    }
  }

  /** Returns all the files in Crosstool + libc. */
  public NestedSet<Artifact> getAllFilesIncludingLibc() throws EvalException {
    try {
      return value.getValue("_all_files_including_libc", Depset.class).getSet(Artifact.class);
    } catch (TypeException e) {
      throw new EvalException(e);
    }
  }

  /** Returns the files necessary for compilation. */
  public NestedSet<Artifact> getCompilerFiles() throws EvalException {
    try {
      return value.getValue("_compiler_files", Depset.class).getSet(Artifact.class);
    } catch (TypeException e) {
      throw new EvalException(e);
    }
  }

  /**
   * Returns the files necessary for compilation excluding headers, assuming that included files
   * will be discovered by input discovery.
   */
  public NestedSet<Artifact> getCompilerFilesWithoutIncludes() throws EvalException {
    try {
      return value
          .getValue("_compiler_files_without_includes", Depset.class)
          .getSet(Artifact.class);
    } catch (TypeException e) {
      throw new EvalException(e);
    }
  }

  /**
   * Returns the files necessary for an 'as' invocation. May be empty if the CROSSTOOL file does not
   * define as_files.
   */
  public NestedSet<Artifact> getAsFiles() throws EvalException {
    try {
      return value.getValue("_as_files", Depset.class).getSet(Artifact.class);
    } catch (TypeException e) {
      throw new EvalException(e);
    }
  }

  /**
   * Returns the files necessary for an 'ar' invocation. May be empty if the CROSSTOOL file does not
   * define ar_files.
   */
  public NestedSet<Artifact> getArFiles() throws EvalException, TypeException {
    return value.getValue("_ar_files", Depset.class).getSet(Artifact.class);
  }

  /** Returns the files necessary for linking, including the files needed for libc. */
  public NestedSet<Artifact> getLinkerFiles() throws EvalException, TypeException {
    return value.getValue("_linker_files", Depset.class).getSet(Artifact.class);
  }

  /** Returns the files necessary for capturing code coverage. */
  @VisibleForTesting
  public NestedSet<Artifact> getCoverageFiles() throws EvalException, TypeException {
    return value.getValue("_coverage_files", Depset.class).getSet(Artifact.class);
  }

  /**
   * Returns true if the featureConfiguration includes statically linking the cpp runtimes.
   *
   * @param featureConfiguration the relevant FeatureConfiguration.
   */
  private static boolean shouldStaticallyLinkCppRuntimes(
      FeatureConfiguration featureConfiguration) {
    return featureConfiguration.isEnabled(CppRuleClasses.STATIC_LINK_CPP_RUNTIMES);
  }

  @Nullable
  public NestedSet<Artifact> getStaticRuntimeLinkInputs() throws EvalException, TypeException {
    return nullOrDepset(value, "_static_runtime_lib_depset");
  }

  /** Returns the static runtime libraries. */
  public static NestedSet<Artifact> getStaticRuntimeLinkInputsOrThrowError(
      NestedSet<Artifact> staticRuntimeLinkInputs, FeatureConfiguration featureConfiguration)
      throws EvalException {
    if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
      if (staticRuntimeLinkInputs == null) {
        throw Starlark.errorf(
            "Toolchain supports embedded runtimes, but didn't provide static_runtime_lib"
                + " attribute.");
      }
      return staticRuntimeLinkInputs;
    } else {
      return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
    }
  }

  @Nullable
  public NestedSet<Artifact> getDynamicRuntimeLinkInputs() throws EvalException, TypeException {
    return nullOrDepset(value, "_dynamic_runtime_lib_depset");
  }

  /** Returns the dynamic runtime libraries. */
  public static NestedSet<Artifact> getDynamicRuntimeLinkInputsOrThrowError(
      NestedSet<Artifact> dynamicRuntimeLinkInputs, FeatureConfiguration featureConfiguration)
      throws EvalException {
    if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
      if (dynamicRuntimeLinkInputs == null) {
        throw new EvalException(
            "Toolchain supports embedded runtimes, but didn't provide dynamic_runtime_lib"
                + " attribute.");
      }
      return dynamicRuntimeLinkInputs;
    } else {
      return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
    }
  }

  /**
   * Returns the name of the directory where the solib symlinks for the dynamic runtime libraries
   * live. The directory itself will be under the root of the exec configuration in the 'bin'
   * directory.
   */
  public PathFragment getDynamicRuntimeSolibDir() throws EvalException {
    return PathFragment.create(value.getValue("dynamic_runtime_solib_dir", String.class));
  }

  /** Returns the {@code CcInfo} for the toolchain. */
  public CcInfo getCcInfo() throws EvalException {
    return value.getValue("_cc_info", CcInfo.class);
  }

  /** Whether the toolchains supports parameter files. */
  public boolean supportsParamFiles() throws EvalException {
    return value.getValue("_supports_param_files", Boolean.class);
  }

  /** Returns the configured features of the toolchain. */
  @Nullable
  public CcToolchainFeatures getFeatures() throws EvalException {
    return value.getValue("_toolchain_features", CcToolchainFeatures.class);
  }

  public Label getCcToolchainLabel() throws EvalException {
    return value.getValue("_toolchain_label", Label.class);
  }

  /**
   * 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() throws EvalException {
    return value.getValue("_solib_dir", String.class);
  }

  /** Returns whether this toolchain supports interface shared libraries. */
  // TODO(gnish): Move this to FeatureConfiguration.
  public static boolean supportsInterfaceSharedLibraries(
      FeatureConfiguration featureConfiguration) {
    return featureConfiguration.isEnabled(CppRuleClasses.SUPPORTS_INTERFACE_SHARED_LIBRARIES);
  }

  /** Return context-sensitive fdo instrumentation path. */
  public String getCSFdoInstrument() throws EvalException {
    CppConfiguration cppConfiguration =
        value.getValue("_cpp_configuration", CppConfiguration.class);
    return cppConfiguration.getCSFdoInstrument();
  }

  public CcToolchainVariables getBuildVars() throws EvalException {
    return getValue().getValue("_build_variables", CcToolchainVariables.class);
  }

  /**
   * Return the set of include files that may be included even if they are not mentioned in the
   * source file or any of the headers included by it.
   */
  public ImmutableList<Artifact> getBuiltinIncludeFiles() throws EvalException {
    return Sequence.cast(
            value.getValue("_builtin_include_files", Sequence.class),
            Artifact.class,
            "_builtin_include_files")
        .getImmutableList();
  }

  /**
   * Returns the tool which should be used for linking dynamic libraries, or in case it's not
   * specified by the crosstool this will be @tools_repository/tools/cpp:link_dynamic_library
   */
  public Artifact getLinkDynamicLibraryTool() throws EvalException {
    return value.getValue("_link_dynamic_library_tool", Artifact.class);
  }

  /** Returns the grep-includes tool which is needing during linking because of linkstamping. */
  @Nullable
  public Artifact getGrepIncludes() throws EvalException {
    return nullIfNone(value, "_grep_includes", Artifact.class);
  }

  /** Returns the tool that builds interface libraries from dynamic libraries. */
  public Artifact getInterfaceSoBuilder() throws EvalException {
    return value.getValue("_if_so_builder", Artifact.class);
  }

  @Nullable
  public String getSysroot() throws EvalException {
    PathFragment sysroot = nullOrPathFragment(value, "sysroot");
    return sysroot != null ? sysroot.getPathString() : null;
  }

  @Nullable
  public PathFragment getSysrootPathFragment() throws EvalException {
    return nullOrPathFragment(value, "sysroot");
  }

  /**
   * 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.
  @VisibleForTesting
  public String getAbi() throws EvalException {
    return value.getValue("_abi", String.class);
  }

  /** Returns the target architecture using blaze-specific constants (e.g. "piii"). */
  public String getTargetCpu() throws EvalException {
    return value.getValue("cpu", String.class);
  }

  /**
   * 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() throws EvalException {
    return value.getValue("_legacy_cc_flags_make_variable", String.class);
  }

  public FdoContext getFdoContext() throws EvalException {
    return value.getValue("_fdo_context", FdoContext.class);
  }

  // Not all of CcToolchainProvider is exposed to Starlark, which makes implementing deep equality
  // impossible: if Java-only parts are considered, the behavior is surprising in Starlark, if they
  // are not, the behavior is surprising in Java. Thus, object identity it is.
  @Override
  public boolean equals(Object other) {
    return other == this;
  }

  @Override
  public int hashCode() {
    return System.identityHashCode(this);
  }

  public boolean isToolConfiguration() throws EvalException {
    return value.getValue("_is_tool_configuration", Boolean.class);
  }

  public PackageSpecificationProvider getAllowlistForLayeringCheck() throws EvalException {
    return value.getValue("_allowlist_for_layering_check", PackageSpecificationProvider.class);
  }

  public OutputGroupInfo getCcBuildInfoTranslator() throws EvalException {
    return value.getValue("_build_info_files", OutputGroupInfo.class);
  }

  public CppConfiguration getCppConfiguration() throws EvalException {
    return value.getValue("_cpp_configuration", CppConfiguration.class);
  }
}
