// Copyright 2021 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 static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableMap.toImmutableMap;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.docgen.annot.DocCategory;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.starlark.StarlarkActionFactory;
import com.google.devtools.build.lib.analysis.starlark.StarlarkRuleContext;
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.packages.Attribute.ComputedDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.cpp.CcLinkingContext.Linkstamp;
import com.google.devtools.build.lib.starlarkbuildapi.NativeComputedDefaultApi;
import com.google.devtools.build.lib.starlarkbuildapi.core.ProviderApi;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import javax.annotation.Nullable;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.ParamType;
import net.starlark.java.annot.StarlarkBuiltin;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.NoneType;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkValue;
import net.starlark.java.syntax.Location;

/** Utility methods for rules in Starlark Builtins */
@StarlarkBuiltin(name = "cc_internal", category = DocCategory.BUILTIN, documented = false)
public class CcStarlarkInternal implements StarlarkValue {

  public static final String NAME = "cc_internal";

  @Nullable
  private PathFragment getPathfragmentOrNone(Object o) {
    String pathString = CcModule.convertFromNoneable(o, null);
    if (pathString == null) {
      return null;
    }
    return PathFragment.create(pathString);
  }

  private ImmutableMap<String, PathFragment> castDict(Dict<?, ?> d) throws EvalException {
    return Dict.cast(d, String.class, String.class, "tool_paths").entrySet().stream()
        .map(p -> Pair.of(p.getKey(), PathFragment.create(p.getValue())))
        .collect(toImmutableMap(Pair::getFirst, Pair::getSecond));
  }

  @StarlarkMethod(
      name = "construct_toolchain_provider",
      documented = false,
      parameters = {
        @Param(name = "ctx", positional = false, named = true),
        @Param(name = "cpp_config", positional = false, named = true),
        @Param(name = "toolchain_features", positional = false, named = true),
        @Param(name = "tools_directory", positional = false, named = true),
        @Param(name = "attributes", positional = false, named = true),
        @Param(
            name = "static_runtime_link_inputs",
            positional = false,
            named = true,
            allowedTypes = {
              @ParamType(type = Depset.class),
              @ParamType(type = NoneType.class),
            }),
        @Param(
            name = "dynamic_runtime_link_symlinks",
            positional = false,
            named = true,
            allowedTypes = {
              @ParamType(type = Depset.class),
              @ParamType(type = NoneType.class),
            }),
        @Param(name = "runtime_solib_dir", positional = false, named = true),
        @Param(name = "cc_compilation_context", positional = false, named = true),
        @Param(name = "builtin_include_files", positional = false, named = true),
        @Param(name = "target_builtin_include_files", positional = false, named = true),
        @Param(name = "builtin_include_directories", positional = false, named = true),
        @Param(name = "sysroot", positional = false, named = true),
        @Param(name = "target_sysroot", positional = false, named = true),
        @Param(name = "fdo_context", positional = false, named = true),
        @Param(name = "is_tool_configuration", positional = false, named = true),
        @Param(name = "tool_paths", positional = false, named = true),
        @Param(name = "toolchain_config_info", positional = false, named = true),
        @Param(name = "default_sysroot", positional = false, named = true),
        @Param(name = "runtime_sysroot", positional = false, named = true),
        @Param(name = "solib_directory", positional = false, named = true),
        @Param(name = "additional_make_variables", positional = false, named = true),
        @Param(name = "legacy_cc_flags_make_variable", positional = false, named = true),
        @Param(name = "objcopy", positional = false, named = true),
        @Param(name = "compiler", positional = false, named = true),
        @Param(name = "preprocessor", positional = false, named = true),
        @Param(name = "nm", positional = false, named = true),
        @Param(name = "objdump", positional = false, named = true),
        @Param(name = "ar", positional = false, named = true),
        @Param(name = "strip", positional = false, named = true),
        @Param(name = "ld", positional = false, named = true),
        @Param(name = "gcov", positional = false, named = true),
      })
  public CcToolchainProvider getCcToolchainProvider(
      StarlarkRuleContext ruleContext,
      Object cppConfigurationObject,
      CcToolchainFeatures toolchainFeatures,
      String toolsDirectoryStr,
      CcToolchainAttributesProvider attributes,
      Object staticRuntimeLinkInputsObject,
      Object dynamicRuntimeLinkInputsObject,
      String dynamicRuntimeSolibDirStr,
      CcCompilationContext ccCompilationContext,
      Sequence<?> builtinIncludeFiles,
      Sequence<?> targetBuiltinIncludeFiles,
      Sequence<?> builtInIncludeDirectoriesStr,
      Object sysrootObject,
      Object targetSysrootObject,
      FdoContext fdoContext,
      boolean isToolConfiguration,
      Dict<?, ?> toolPathsDict,
      CcToolchainConfigInfo toolchainConfigInfo,
      Object defaultSysrootObject,
      Object runtimeSysrootObject,
      String solibDirectory,
      Dict<?, ?> additionalMakeVariablesDict,
      String legacyCcFlagsMakeVariable,
      String objcopyExecutable,
      String compilerExecutable,
      String preprocessorExecutable,
      String nmExecutable,
      String objdumpExecutable,
      String arExecutable,
      String stripExecutable,
      String ldExecutable,
      String gcovExecutable)
      throws EvalException {
    CppConfiguration cppConfiguration = CcModule.convertFromNoneable(cppConfigurationObject, null);
    PathFragment toolsDirectory = PathFragment.create(toolsDirectoryStr);
    NestedSet<Artifact> staticRuntimeLinkInputsSet = null;
    NestedSet<Artifact> dynamicRuntimeLinkInputsSet = null;
    try {
      if (staticRuntimeLinkInputsObject != Starlark.NONE) {
        staticRuntimeLinkInputsSet =
            ((Depset) staticRuntimeLinkInputsObject).getSet(Artifact.class);
      }
      if (dynamicRuntimeLinkInputsObject != Starlark.NONE) {
        dynamicRuntimeLinkInputsSet =
            ((Depset) dynamicRuntimeLinkInputsObject).getSet(Artifact.class);
      }
    } catch (TypeException e) {
      throw new EvalException(e);
    }
    PathFragment dynamicRuntimeSolibDir = PathFragment.create(dynamicRuntimeSolibDirStr);
    ImmutableList<PathFragment> builtInIncludeDirectories =
        Sequence.cast(builtInIncludeDirectoriesStr, String.class, "builtin_include_directories")
            .stream()
            .map(PathFragment::create)
            .collect(toImmutableList());
    PathFragment sysroot = getPathfragmentOrNone(sysrootObject);
    PathFragment targetSysroot = getPathfragmentOrNone(targetSysrootObject);
    Dict<String, String> additionalMakeVariables =
        Dict.cast(additionalMakeVariablesDict, String.class, String.class, "tool_paths");
    PathFragment defaultSysroot = getPathfragmentOrNone(defaultSysrootObject);
    PathFragment runtimeSysroot = getPathfragmentOrNone(runtimeSysrootObject);

    return new CcToolchainProvider(
        /* cppConfiguration= */ cppConfiguration,
        /* toolchainFeatures= */ toolchainFeatures,
        /* crosstoolTopPathFragment= */ toolsDirectory,
        /* allFiles= */ attributes.getAllFiles(),
        /* allFilesIncludingLibc= */ attributes.getFullInputsForCrosstool(),
        /* compilerFiles= */ attributes.getCompilerFiles(),
        /* compilerFilesWithoutIncludes= */ attributes.getCompilerFilesWithoutIncludes(),
        /* stripFiles= */ attributes.getStripFiles(),
        /* objcopyFiles= */ attributes.getObjcopyFiles(),
        /* asFiles= */ attributes.getAsFiles(),
        /* arFiles= */ attributes.getArFiles(),
        /* linkerFiles= */ attributes.getFullInputsForLink(),
        /* interfaceSoBuilder= */ attributes.getIfsoBuilder(),
        /* dwpFiles= */ attributes.getDwpFiles(),
        /* coverageFiles= */ attributes.getCoverage(),
        /* libcLink= */ attributes.getLibc(),
        /* targetLibcLink= */ attributes.getTargetLibc(),
        /* staticRuntimeLinkInputs= */ staticRuntimeLinkInputsSet,
        /* dynamicRuntimeLinkInputs= */ dynamicRuntimeLinkInputsSet,
        /* dynamicRuntimeSolibDir= */ dynamicRuntimeSolibDir,
        /* ccCompilationContext= */ ccCompilationContext,
        /* supportsParamFiles= */ attributes.isSupportsParamFiles(),
        /* supportsHeaderParsing= */ attributes.isSupportsHeaderParsing(),
        /* additionalBuildVariablesComputer= */ attributes.getAdditionalBuildVariablesComputer(),
        /* buildVariables= */ CcToolchainProviderHelper.getBuildVariables(
            ruleContext.getRuleContext().getConfiguration().getOptions(),
            cppConfiguration,
            sysroot,
            attributes.getAdditionalBuildVariablesComputer()),
        /* builtinIncludeFiles= */ Sequence.cast(
                builtinIncludeFiles, Artifact.class, "builtin_include_files")
            .getImmutableList(),
        /* targetBuiltinIncludeFiles= */ Sequence.cast(
                targetBuiltinIncludeFiles, Artifact.class, "target_builtin_include_files")
            .getImmutableList(),
        /* linkDynamicLibraryTool= */ attributes.getLinkDynamicLibraryTool(),
        /* grepIncludes= */ attributes.getGrepIncludes(),
        /* builtInIncludeDirectories= */ builtInIncludeDirectories,
        /* sysroot= */ sysroot,
        /* targetSysroot= */ targetSysroot,
        /* fdoContext= */ fdoContext,
        /* isToolConfiguration= */ isToolConfiguration,
        /* licensesProvider= */ attributes.getLicensesProvider(),
        /* toolPaths= */ castDict(toolPathsDict),
        /* toolchainIdentifier= */ toolchainConfigInfo.getToolchainIdentifier(),
        /* compiler= */ toolchainConfigInfo.getCompiler(),
        /* abiGlibcVersion= */ toolchainConfigInfo.getAbiLibcVersion(),
        /* targetCpu= */ toolchainConfigInfo.getTargetCpu(),
        /* targetOS= */ toolchainConfigInfo.getCcTargetOs(),
        /* defaultSysroot= */ defaultSysroot,
        /* runtimeSysroot= */ runtimeSysroot,
        /* targetLibc= */ toolchainConfigInfo.getTargetLibc(),
        /* ccToolchainLabel= */ ruleContext.getRuleContext().getLabel(),
        /* solibDirectory= */ solibDirectory,
        /* abi= */ toolchainConfigInfo.getAbiVersion(),
        /* targetSystemName= */ toolchainConfigInfo.getTargetSystemName(),
        /* additionalMakeVariables= */ ImmutableMap.copyOf(additionalMakeVariables),
        /* legacyCcFlagsMakeVariable= */ legacyCcFlagsMakeVariable,
        /* allowlistForLayeringCheck= */ attributes.getAllowlistForLayeringCheck(),
        /* allowListForLooseHeaderCheck= */ attributes.getAllowlistForLooseHeaderCheck(),
        /* objcopyExecutable= */ objcopyExecutable,
        /* compilerExecutable= */ compilerExecutable,
        /* preprocessorExecutable= */ preprocessorExecutable,
        /* nmExecutable= */ nmExecutable,
        /* objdumpExecutable= */ objdumpExecutable,
        /* arExecutable= */ arExecutable,
        /* stripExecutable= */ stripExecutable,
        /* ldExecutable= */ ldExecutable,
        /* gcovExecutable= */ gcovExecutable);
  }

  @StarlarkMethod(
      name = "solib_symlink_action",
      documented = false,
      parameters = {
        @Param(name = "ctx", positional = false, named = true),
        @Param(name = "artifact", positional = false, named = true),
        @Param(name = "solib_directory", positional = false, named = true),
        @Param(name = "runtime_solib_dir_base", positional = false, named = true),
      })
  public Artifact solibSymlinkAction(
      StarlarkRuleContext ruleContext,
      Artifact artifact,
      String solibDirectory,
      String runtimeSolibDirBase) {
    return SolibSymlinkAction.getCppRuntimeSymlink(
        ruleContext.getRuleContext(), artifact, solibDirectory, runtimeSolibDirBase);
  }

  @StarlarkMethod(
      name = "fdo_context",
      documented = false,
      parameters = {
        @Param(name = "ctx", positional = false, named = true),
        @Param(name = "attributes", positional = false, named = true),
        @Param(name = "configuration", positional = false, named = true),
        @Param(name = "cpp_config", positional = false, named = true),
        @Param(name = "tool_paths", positional = false, named = true),
      },
      allowReturnNones = true)
  @Nullable
  public FdoContext fdoContext(
      StarlarkRuleContext ruleContext,
      CcToolchainAttributesProvider attributes,
      BuildConfigurationValue configuration,
      CppConfiguration cppConfiguration,
      Dict<?, ?> toolPathsDict)
      throws EvalException, InterruptedException {
    try {
      return FdoHelper.getFdoContext(
          ruleContext.getRuleContext(),
          attributes,
          configuration,
          cppConfiguration,
          castDict(toolPathsDict));
    } catch (RuleErrorException e) {
      throw new EvalException(e);
    }
  }

  @StarlarkMethod(
      name = "cc_toolchain_features",
      documented = false,
      parameters = {
        @Param(name = "toolchain_config_info", positional = false, named = true),
        @Param(name = "tools_directory", positional = false, named = true),
      })
  public CcToolchainFeatures ccToolchainFeatures(
      CcToolchainConfigInfo ccToolchainConfigInfo, String toolsDirectoryPathString)
      throws EvalException {
    return new CcToolchainFeatures(
        ccToolchainConfigInfo, PathFragment.create(toolsDirectoryPathString));
  }

  @StarlarkMethod(
      name = "is_package_headers_checking_mode_set",
      documented = false,
      parameters = {@Param(name = "ctx", positional = false, named = true)})
  public boolean isPackageHeadersCheckingModeSetForStarlark(
      StarlarkRuleContext starlarkRuleContext) {
    return starlarkRuleContext.getRuleContext().getRule().getPackage().isDefaultHdrsCheckSet();
  }

  @StarlarkMethod(
      name = "package_headers_checking_mode",
      documented = false,
      parameters = {@Param(name = "ctx", positional = false, named = true)})
  public String getPackageHeadersCheckingModeForStarlark(StarlarkRuleContext starlarkRuleContext) {
    return starlarkRuleContext.getRuleContext().getRule().getPackage().getDefaultHdrsCheck();
  }

  @StarlarkMethod(
      name = "is_package_headers_checking_mode_set_for_aspect",
      documented = false,
      parameters = {@Param(name = "ctx", positional = false, named = true)})
  public boolean isPackageHeadersCheckingModeSetForStarlarkAspect(
      StarlarkRuleContext starlarkRuleContext) {
    return starlarkRuleContext.getRuleContext().getTarget().getPackage().isDefaultHdrsCheckSet();
  }

  @StarlarkMethod(
      name = "package_headers_checking_mode_for_aspect",
      documented = false,
      parameters = {@Param(name = "ctx", positional = false, named = true)})
  public String getPackageHeadersCheckingModeForStarlarkAspect(
      StarlarkRuleContext starlarkRuleContext) {
    return starlarkRuleContext.getRuleContext().getTarget().getPackage().getDefaultHdrsCheck();
  }

  @StarlarkMethod(
      name = "create_common",
      documented = false,
      parameters = {
        @Param(name = "ctx", positional = false, named = true),
      })
  public CcCommon createCommon(StarlarkRuleContext starlarkRuleContext) throws EvalException {
    try {
      return new CcCommon(starlarkRuleContext.getRuleContext());
    } catch (RuleErrorException e) {
      throw new EvalException(e);
    }
  }

  @StarlarkMethod(name = "launcher_provider", documented = false, structField = true)
  public ProviderApi getCcLauncherInfoProvider() throws EvalException {
    return CcLauncherInfo.PROVIDER;
  }

  @StarlarkMethod(
      name = "create_linkstamp",
      documented = false,
      parameters = {
        @Param(name = "actions", positional = false, named = true),
        @Param(name = "linkstamp", positional = false, named = true),
        @Param(name = "compilation_context", positional = false, named = true),
      })
  public Linkstamp createLinkstamp(
      StarlarkActionFactory starlarkActionFactoryApi,
      Artifact linkstamp,
      CcCompilationContext ccCompilationContext)
      throws EvalException {
    try {
      return new Linkstamp( // throws InterruptedException
          linkstamp,
          ccCompilationContext.getDeclaredIncludeSrcs(),
          starlarkActionFactoryApi.getActionConstructionContext().getActionKeyContext());
    } catch (CommandLineExpansionException | InterruptedException ex) {
      throw new EvalException(ex);
    }
  }

  static class DefaultHdrsCheckBuiltinComputedDefault extends ComputedDefault
      implements NativeComputedDefaultApi {
    @Override
    public Object getDefault(AttributeMap rule) {
      return rule.isPackageDefaultHdrsCheckSet() ? rule.getPackageDefaultHdrsCheck() : "";
    }

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

  @StarlarkMethod(name = "default_hdrs_check_computed_default", documented = false)
  public ComputedDefault getDefaultHdrsCheckComputedDefault() {
    return new DefaultHdrsCheckBuiltinComputedDefault();
  }

  static class DefParserComputedDefault extends ComputedDefault
      implements NativeComputedDefaultApi {
    @Override
    @Nullable
    public Object getDefault(AttributeMap rule) {
      // Every cc_rule depends implicitly on the def_parser tool.
      // The only exceptions are the rules for building def_parser itself.
      // To avoid cycles in the dependency graph, return null for rules under
      // @bazel_tools//third_party/def_parser and @bazel_tools//tools/cpp
      String label = rule.getLabel().toString();
      return label.startsWith("@bazel_tools//third_party/def_parser")
              // @bazel_tools//tools/cpp:malloc and @bazel_tools//tools/cpp:stl
              // are implicit dependencies of all cc rules,
              // thus a dependency of the def_parser.
              || label.startsWith("@bazel_tools//tools/cpp")
          ? null
          : Label.parseCanonicalUnchecked("@bazel_tools//tools/def_parser:def_parser");
    }

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

  @StarlarkMethod(name = "def_parser_computed_default", documented = false)
  public ComputedDefault getDefParserComputedDefault() {
    return new DefParserComputedDefault();
  }

  /**
   * TODO(bazel-team): This can be re-written directly to Starlark but it will cause a memory
   * regression due to the way StarlarkComputedDefault is stored for each rule.
   */
  static class StlComputedDefault extends ComputedDefault implements NativeComputedDefaultApi {
    @Override
    @Nullable
    public Object getDefault(AttributeMap rule) {
      return rule.getOrDefault("tags", Type.STRING_LIST, ImmutableList.of()).contains("__CC_STL__")
          ? null
          : Label.parseCanonicalUnchecked("@//third_party/stl");
    }

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

  @StarlarkMethod(name = "stl_computed_default", documented = false)
  public ComputedDefault getStlComputedDefault() {
    return new StlComputedDefault();
  }

  @StarlarkMethod(
      name = "create_cc_launcher_info",
      doc = "Create a CcLauncherInfo instance.",
      parameters = {
        @Param(
            name = "cc_info",
            positional = false,
            named = true,
            doc = "CcInfo instance.",
            allowedTypes = {@ParamType(type = CcInfo.class)}),
        @Param(
            name = "compilation_outputs",
            positional = false,
            named = true,
            doc = "CcCompilationOutputs instance.",
            allowedTypes = {@ParamType(type = CcCompilationOutputs.class)})
      })
  public CcLauncherInfo createCcLauncherInfo(
      CcInfo ccInfo, CcCompilationOutputs compilationOutputs) {
    return new CcLauncherInfo(ccInfo, compilationOutputs);
  }

  private static final StarlarkProvider starlarkCcTestRunnerInfo =
      StarlarkProvider.builder(Location.BUILTIN)
          .setExported(
              new StarlarkProvider.Key(
                  Label.parseCanonicalUnchecked("//tools/cpp/cc_test:toolchain.bzl"),
                  "CcTestRunnerInfo"))
          .build();

  @StarlarkMethod(name = "CcTestRunnerInfo", documented = false, structField = true)
  public StarlarkProvider ccTestRunnerInfo() throws EvalException {
    return starlarkCcTestRunnerInfo;
  }
}
