// Copyright 2020 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.skyframe;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.analysis.util.MockRuleDefaults;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import net.starlark.java.eval.FlagGuardedValue;
import net.starlark.java.eval.Mutability;
import net.starlark.java.eval.StarlarkList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for Starlark builtin injection.
 *
 * <p>Essentially these are integration tests between {@link StarlarkBuiltinsFunction}, {@link
 * BzlLoadFunction}, and the rest of package loading.
 */
@RunWith(JUnit4.class)
public class BuiltinsInjectionTest extends BuildViewTestCase {

  /** A simple dummy rule that doesn't do anything. */
  private static final MockRule OVERRIDABLE_RULE = () -> MockRule.define("overridable_rule");

  /**
   * A dummy native rule that reads a value from {@code @_builtins}.
   *
   * <p>It looks up the symbol "builtins_defined_symbol" in exported_to_java, and prints its value
   * to the event handler.
   */
  private static final MockRule SANDWICH_RULE =
      () -> MockRule.factory(SandwichFactory.class).define("sandwich_rule");

  // Must be public due to reflective construction of rule factories.
  /** Factory for SANDWICH_RULE. (Javadoc'd to pacify linter.) */
  public static class SandwichFactory extends MockRuleDefaults.DefaultConfiguredTargetFactory {
    @Override
    public ConfiguredTarget create(RuleContext ruleContext)
        throws InterruptedException, RuleErrorException, ActionConflictException {
      Object value = ruleContext.getStarlarkDefinedBuiltin("builtins_defined_symbol");
      EventHandler handler = ruleContext.getAnalysisEnvironment().getEventHandler();
      handler.handle(Event.info("builtins_defined_symbol :: " + value.toString()));
      return super.create(ruleContext);
    }
  }

  /**
   * A dummy native rule that runs {@code @_builtins}-defined code.
   *
   * <p>It looks up the function listed as "builtins_defined_logic" in exported_to_java, and calls
   * it twice on an initially empty list. It prints both return values and the final value of the
   * list. On Starlark evaluation error, it reports a rule error.
   */
  private static final MockRule SANDWICH_LOGIC_RULE =
      () -> MockRule.factory(SandwichLogicFactory.class).define("sandwich_logic_rule");

  // Must be public due to reflective construction of rule factories.
  /** Factory for SANDWICH_LOGIC_RULE. (Javadoc'd to pacify linter.) */
  public static class SandwichLogicFactory extends MockRuleDefaults.DefaultConfiguredTargetFactory {
    @Override
    public ConfiguredTarget create(RuleContext ruleContext)
        throws InterruptedException, RuleErrorException, ActionConflictException {
      Mutability mu = ruleContext.getStarlarkThread().mutability();
      Object func = ruleContext.getStarlarkDefinedBuiltin("builtins_defined_logic");
      Object arg = StarlarkList.newList(mu);
      Object return1 =
          ruleContext.callStarlarkOrThrowRuleError(
              func, /*args=*/ ImmutableList.of(arg), /*kwargs=*/ ImmutableMap.of());
      Object return2 =
          ruleContext.callStarlarkOrThrowRuleError(
              func, /*args=*/ ImmutableList.of(arg), /*kwargs=*/ ImmutableMap.of());

      EventHandler handler = ruleContext.getAnalysisEnvironment().getEventHandler();
      handler.handle(Event.info("builtins_defined_logic call 1 :: " + return1.toString()));
      handler.handle(Event.info("builtins_defined_logic call 2 :: " + return2.toString()));
      handler.handle(Event.info("final list value :: " + arg.toString()));
      return super.create(ruleContext);
    }
  }

  /**
   * A dummy native rule that passes a Starlark rule context ({@code ctx}) object to
   * {@code @_builtins}-defined code.
   *
   * <p>It looks up "builtins_rule_impl_helper" in exported_to_java, and calls it with {@code ctx}
   * as its sole arg. The rule has a "content" string attribute and "out" output label attribute.
   * The Starlark helper function is responsible for registering an action to generate the output.
   */
  private static final MockRule SANDWICH_CTX_RULE =
      () ->
          MockRule.factory(SandwichCtxFactory.class)
              .define(
                  "sandwich_ctx_rule",
                  Attribute.attr("content", Type.STRING),
                  Attribute.attr("out", BuildType.OUTPUT));

  // Must be public due to reflective construction of rule factories.
  /** Factory for SANDWICH_CTX_RULE. (Javadoc'd to pacify linter.) */
  public static class SandwichCtxFactory extends MockRuleDefaults.DefaultConfiguredTargetFactory {
    @Override
    public ConfiguredTarget create(RuleContext ruleContext)
        throws InterruptedException, RuleErrorException, ActionConflictException {
      ruleContext.initStarlarkRuleContext();
      ruleContext.callStarlarkOrThrowRuleError(
          ruleContext.getStarlarkDefinedBuiltin("builtins_rule_impl_helper"),
          /*args=*/ ImmutableList.of(ruleContext.getStarlarkRuleContext()),
          /*kwargs=*/ ImmutableMap.of());
      // Don't dispatch to super.create(), which would attempt to register an action to produce
      // "out".
      return new RuleConfiguredTargetBuilder(ruleContext)
          .setFilesToBuild(
              NestedSetBuilder.wrap(Order.STABLE_ORDER, ruleContext.getOutputArtifacts()))
          .setRunfilesSupport(null, null)
          .add(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY))
          .build();
    }
  }

  @Override
  protected Iterable<String> getDefaultsForConfiguration() {
    // Override BuildViewTestCase's behavior of setting all sorts of extra options that don't exist
    // on our minimal rule class provider.
    // We do need the host platform. Set it to something trivial.
    return ImmutableList.of("--host_platform=//minimal_buildenv/platforms:default_host");
  }

  @Override
  protected void initializeMockClient() throws IOException {
    // Don't let the AnalysisMock sneak in any WORKSPACE file content, which may depend on
    // repository rules that our minimal rule class provider doesn't have.
    analysisMock.setupMockClient(mockToolsConfig, ImmutableList.of());
    // Provide a trivial platform definition.
    mockToolsConfig.create(
        "minimal_buildenv/platforms/BUILD", //
        "platform(name = 'default_host')");
  }

  @Override
  protected ConfiguredRuleClassProvider createRuleClassProvider() {
    // Set up a bare-bones ConfiguredRuleClassProvider. Aside from being minimalistic, this heads
    // off the possibility that we somehow grow an implicit dependency on production builtins code,
    // which would break since we're overwriting --experimental_builtins_bzl_path.
    ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
    TestRuleClassProvider.addMinimalRules(builder);
    // Add some mock symbols to override.
    builder
        .addRuleDefinition(OVERRIDABLE_RULE)
        .addRuleDefinition(SANDWICH_RULE)
        .addRuleDefinition(SANDWICH_LOGIC_RULE)
        .addRuleDefinition(SANDWICH_CTX_RULE)
        .addBzlToplevel("overridable_symbol", "original_value")
        .addBzlToplevel(
            "flag_guarded_symbol",
            // For this mock symbol, we reuse the same flag that guards the production
            // _builtins_dummy symbol.
            FlagGuardedValue.onlyWhenExperimentalFlagIsTrue(
                BuildLanguageOptions.EXPERIMENTAL_BUILTINS_DUMMY, "original_value"))
        .addStarlarkBuiltinsInternal("internal_symbol", "internal_value");
    return builder.build();
  }

  @Before
  public void setUp() throws Exception {
    setBuildLanguageOptionsWithBuiltinsStaging();
  }

  private void setBuildLanguageOptionsWithBuiltinsStaging(String... options) throws Exception {
    ArrayList<String> newOptions = new ArrayList<>();
    newOptions.add("--experimental_builtins_bzl_path=tools/builtins_staging");
    Collections.addAll(newOptions, options);
    setBuildLanguageOptions(newOptions.toArray(new String[] {}));
  }

  /**
   * Writes an exports.bzl file with the given content, in the builtins location.
   *
   * <p>See {@link StarlarkBuiltinsFunction#EXPORTS_ENTRYPOINT} for the significance of exports.bzl.
   */
  private void writeExportsBzl(String... lines) throws Exception {
    scratch.overwriteFile("tools/builtins_staging/exports.bzl", lines);
  }

  /**
   * Writes a pkg/dummy.bzl file with the given content. Meant to be used in conjunction with {@link
   * #writePkgBuild}.
   *
   * <p>The bzl prints a marker phrase when it finishes evaluating, and includes a dummy symbol for
   * the BUILD file to load.
   */
  private void writePkgBzl(String... lines) throws Exception {
    List<String> modifiedLines = new ArrayList<>(Arrays.asList(lines));
    modifiedLines.add("dummy_symbol = None");
    // The marker phrase might not be needed, but I don't entirely trust BuildViewTestCase.
    modifiedLines.add("print('dummy.bzl evaluation completed')");
    scratch.overwriteFile("pkg/dummy.bzl", modifiedLines.toArray(lines));
  }

  /**
   * Writes a pkg/BUILD file with the given content. Meant to be used in conjunction with {@link
   * #writePkgBzl}.
   *
   * <p>The BUILD file ensures the dummy.bzl file is loaded.
   */
  private void writePkgBuild(String... lines) throws Exception {
    List<String> modifiedLines = new ArrayList<>(Arrays.asList(lines));
    modifiedLines.add(0, "load(':dummy.bzl', 'dummy_symbol')");
    scratch.overwriteFile("pkg/BUILD", modifiedLines.toArray(lines));
  }

  /** Builds {@code //pkg} and asserts success, including that the marker print() event occurs. */
  private void buildAndAssertSuccess() throws Exception {
    Object result = getConfiguredTarget("//pkg:BUILD");
    assertContainsEvent("dummy.bzl evaluation completed");
    // On error, getConfiguredTarget sometimes returns null without emitting events; see b/26382502.
    // Though in that case it seems unlikely the above assertion would've passed.
    assertThat(result).isNotNull();
  }

  /** Builds {@code //pkg:dummy} and asserts on the absence of the marker print() event. */
  private void buildAndAssertFailure() throws Exception {
    reporter.removeHandler(failFastHandler);
    Object result = getConfiguredTarget("//pkg:BUILD");
    assertDoesNotContainEvent("dummy.bzl evaluation completed");
    assertWithMessage("Loading of //pkg succeeded unexpectedly").that(result).isNull();
  }

  @Test
  public void basicFunctionality() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {'overridable_symbol': 'new_value'}",
        "exported_rules = {'overridable_rule': 'new_rule'}",
        "exported_to_java = {}");
    writePkgBuild("print('In BUILD: overridable_rule :: %s' % overridable_rule)");
    writePkgBzl(
        "print('In bzl: overridable_symbol :: %s' % overridable_symbol)",
        "print('In bzl: overridable_rule :: %s' % native.overridable_rule)");

    buildAndAssertSuccess();
    assertContainsEvent("In bzl: overridable_symbol :: new_value");
    assertContainsEvent("In bzl: overridable_rule :: new_rule");
    assertContainsEvent("In BUILD: overridable_rule :: new_rule");
  }

  @Test
  public void injectedBzlToplevelsAreNotVisibleToBuild() throws Exception {
    // The bzl toplevel symbols aren't toplevels for BUILD files. We test that injecting them
    // doesn't somehow change that.
    writeExportsBzl(
        "exported_toplevels = {'overridable_symbol': 'new_value'}", //
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild("overridable_symbol");
    writePkgBzl();

    buildAndAssertFailure();
    assertContainsEvent("name 'overridable_symbol' is not defined");
  }

  @Test
  public void builtinsCanLoadFromBuiltins() throws Exception {
    // Define a few files that we can load with different kinds of label syntax. In each case,
    // access the `_builtins` symbol to demonstrate that we're being loaded as a builtins bzl.
    scratch.file(
        "tools/builtins_staging/absolute.bzl", //
        "_builtins",
        "a = 'A'");
    scratch.file(
        "tools/builtins_staging/repo_relative.bzl", //
        "_builtins",
        "b = 'B'");
    scratch.file(
        "tools/builtins_staging/subdir/pkg_relative1.bzl", //
        // Do a relative load within a load, to show it's relative to the (pseudo) package, i.e. the
        // root, and not relative to the file. That is, we specify 'subdir/pkg_relative2.bzl', not
        // just 'pkg_relative2.bzl'.
        "load('subdir/pkg_relative2.bzl', 'c2')",
        "_builtins",
        "c = c2");
    scratch.file(
        "tools/builtins_staging/subdir/pkg_relative2.bzl", //
        "_builtins",
        "c2 = 'C'");

    // Also create a file in the main repo whose package path coincides with a file in the builtins
    // pseudo-repo, to show that we get the right one.
    scratch.file("BUILD");
    scratch.file("repo_relative.bzl");

    writeExportsBzl(
        "load('@_builtins//:absolute.bzl', 'a')",
        "load('//:repo_relative.bzl', 'b')", // default repo is @_builtins, not main repo
        "load('subdir/pkg_relative1.bzl', 'c')", // relative to (pseudo) package, which is repo root
        "exported_toplevels = {'overridable_symbol': a + b + c}",
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl("print('overridable_symbol :: %s' % overridable_symbol)");

    buildAndAssertSuccess();
    assertContainsEvent("overridable_symbol :: ABC");
  }

  @Test
  public void otherBzlsCannotLoadFromBuiltins() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {}", //
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl("load('@_builtins//:exports.bzl', 'exported_toplevels')");

    buildAndAssertFailure();
    assertContainsEvent("The repository '@_builtins' could not be resolved");
  }

  @Test
  public void builtinsCannotLoadFromNonBuiltins() throws Exception {
    scratch.file("BUILD");
    scratch.file(
        "a_user_written.bzl", //
        "toplevels = {'overridable_symbol': 'new_value'}");
    writeExportsBzl(
        // Use @// syntax to specify the main repo. Otherwise, the load would be relative to the
        // @_builtins pseudo-repo.
        "load('@//:a_user_written.bzl', 'toplevels')",
        "exported_toplevels = toplevels",
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    buildAndAssertFailure();
    assertContainsEvent(
        "in load statement: .bzl files in @_builtins cannot load from outside of @_builtins");
  }

  @Test
  public void builtinsCannotLoadWithMisplacedColon() throws Exception {
    scratch.file(
        "tools/builtins_staging/subdir/helper.bzl", //
        "toplevels = {'overridable_symbol': 'new_value'}");
    writeExportsBzl(
        "load('//subdir:helper.bzl', 'toplevels')", // Should've been loaded as //:subdir/helper.bzl
        "exported_toplevels = toplevels",
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    buildAndAssertFailure();
    assertContainsEvent("@_builtins cannot have subpackages");
  }

  @Test
  public void errorInEvaluatingBuiltinsTransitiveDependency() throws Exception {
    // Test case with a deep Starlark error in the @_builtins pseudo-repo itself.
    // Note that BzlLoadFunctionTest and PackageLoadingFunctionTest already cover the general case
    // of a failure in retrieving the StarlarkBuiltinsValue. Here we mainly want to make sure the
    // stack trace is informative for errors that occur in dependencies of exports.bzl.
    scratch.file(
        "tools/builtins_staging/helper.bzl", //
        "toplevels = {'overridable_symbol': 1//0}  # <-- dynamic error");
    writeExportsBzl(
        "load('@_builtins//:helper.bzl', 'toplevels')",
        "exported_toplevels = toplevels",
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    buildAndAssertFailure();
    assertContainsEvent(
        "File \"/workspace/tools/builtins_staging/helper.bzl\", line 1, column 37, in <toplevel>");
    assertContainsEvent("Error: integer division by zero");

    // We assert only the parts of the message before and after the module name, since the module
    // identified by the message depends on whether or not the test environment has a prelude file.
    Event ev = assertContainsEvent("Internal error while loading Starlark builtins");
    assertThat(ev.getMessage())
        .contains(
            "Failed to load builtins sources: "
                + "at /workspace/tools/builtins_staging/exports.bzl:1:6: "
                + "initialization of module 'helper.bzl' (internal) failed");
  }

  @Test
  public void errorInProcessingExports() throws Exception {
    // Test case with an error in the symbols exported by exports.bzl, but no actual Starlark errors
    // in the builtins files themselves.
    writeExportsBzl(
        "exported_toplevels = None", // should be dict
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    buildAndAssertFailure();

    // We assert only the parts of the message before and after the module name, since the module
    // identified by the message depends on whether or not the test environment has a prelude file.
    Event ev = assertContainsEvent("Internal error while loading Starlark builtins");
    assertThat(ev.getMessage())
        .contains(
            "Failed to apply declared builtins: "
                + "got NoneType for 'exported_toplevels dict', want dict");
  }

  // TODO(#11437): Remove once disabling is not allowed.
  @Test
  public void injectionDisabledByFlag() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {'overridable_symbol': 'new_value'}",
        "exported_rules = {'overridable_rule': 'new_rule'}",
        "exported_to_java = {}");
    writePkgBuild("print('In BUILD: overridable_rule :: %s' % overridable_rule)");
    writePkgBzl(
        "print('In bzl: overridable_symbol :: %s' % overridable_symbol)",
        "print('In bzl: overridable_rule :: %s' % native.overridable_rule)");
    setBuildLanguageOptions("--experimental_builtins_bzl_path=");

    buildAndAssertSuccess();
    assertContainsEvent("In bzl: overridable_symbol :: original_value");
    assertContainsEvent("In bzl: overridable_rule :: <built-in rule overridable_rule>");
    assertContainsEvent("In BUILD: overridable_rule :: <built-in rule overridable_rule>");
  }

  // TODO(#11437): Remove once disabling is not allowed.
  @Test
  public void exportsBzlMayBeInErrorWhenInjectionIsDisabled() throws Exception {
    writeExportsBzl( //
        "PARSE ERROR");
    writePkgBuild("print('In BUILD: overridable_rule :: %s' % overridable_rule)");
    writePkgBzl(
        "print('In bzl: overridable_symbol :: %s' % overridable_symbol)",
        "print('In bzl: overridable_rule :: %s' % native.overridable_rule)");
    setBuildLanguageOptions("--experimental_builtins_bzl_path=");

    buildAndAssertSuccess();
    assertContainsEvent("In bzl: overridable_symbol :: original_value");
    assertContainsEvent("In bzl: overridable_rule :: <built-in rule overridable_rule>");
    assertContainsEvent("In BUILD: overridable_rule :: <built-in rule overridable_rule>");
  }

  @Test
  public void workspaceLoadedBzlUsesInjectionButNotWORKSPACE() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {'overridable_symbol': 'new_value'}",
        "exported_rules = {'overridable_rule': 'new_rule'}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();
    scratch.appendFile(
        "WORKSPACE", //
        "load(':foo.bzl', 'dummy_symbol')",
        "print('In WORKSPACE: overridable_rule :: %s' % overridable_rule)",
        "print(dummy_symbol)");
    scratch.file("BUILD");
    scratch.file(
        "foo.bzl",
        "dummy_symbol = None",
        "print('In bzl: overridable_symbol :: %s' % overridable_symbol)");

    buildAndAssertSuccess();
    // Builtins for WORKSPACE bzls are populated the same as for BUILD bzls.
    assertContainsEvent("In bzl: overridable_symbol :: new_value");
    // We don't assert that the rule isn't injected because the workspace native object doesn't
    // contain our original mock rule. We can test this for WORKSPACE files at the top-level though.
    assertContainsEvent("In WORKSPACE: overridable_rule :: <built-in function overridable_rule>");
  }

  @Test
  public void builtinsCanSeeOriginalNativeToplevels() throws Exception {
    writeExportsBzl(
        "print('In builtins: overridable_symbol :: %s' % _builtins.toplevel.overridable_symbol)",
        "exported_toplevels = {'overridable_symbol': 'new_value'}",
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl("print('In bzl: overridable_symbol :: %s' % overridable_symbol)");

    buildAndAssertSuccess();
    assertContainsEvent("In builtins: overridable_symbol :: original_value");
    assertContainsEvent("In bzl: overridable_symbol :: new_value");
  }

  @Test
  public void builtinsCanSeeOriginalNativeRules() throws Exception {
    writeExportsBzl(
        "print('In builtins: overridable_rule :: %s' % _builtins.native.overridable_rule)",
        "exported_toplevels = {}",
        "exported_rules = {'overridable_rule': 'new_rule'}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl("print('In bzl: overridable_rule :: %s' % native.overridable_rule)");

    buildAndAssertSuccess();
    assertContainsEvent("In builtins: overridable_rule :: <built-in rule overridable_rule>");
    assertContainsEvent("In bzl: overridable_rule :: new_rule");
  }

  @Test
  public void builtinsCanSeeBuiltinsInternalSymbol() throws Exception {
    writeExportsBzl(
        "print('internal_symbol :: %s' % _builtins.internal.internal_symbol)",
        "exported_toplevels = {}", //
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    buildAndAssertSuccess();
    assertContainsEvent("internal_symbol :: internal_value");
  }

  @Test
  public void otherBzlsCannotSeeBuiltinsInternalSymbol() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {}", //
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl("internal_symbol");

    buildAndAssertFailure();
    assertContainsEvent("name 'internal_symbol' is not defined");
  }

  @Test
  public void builtinsCanSeeFlags_unset() throws Exception {
    writeExportsBzl(
        // We use a None default here, but note that that's brittle if any machinery explicitly sets
        // flags to their default values. In practice the flag's real default value should be used.
        "print('experimental_builtins_dummy :: %s' % ",
        "      _builtins.get_flag('experimental_builtins_dummy', None))",
        "exported_toplevels = {}", //
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    buildAndAssertSuccess();
    assertContainsEvent("experimental_builtins_dummy :: None");
  }

  @Test
  public void builtinsCanSeeFlags_set() throws Exception {
    writeExportsBzl(
        "print('experimental_builtins_dummy :: %s' % ",
        "      _builtins.get_flag('experimental_builtins_dummy', None))",
        "exported_toplevels = {}", //
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    setBuildLanguageOptionsWithBuiltinsStaging("--experimental_builtins_dummy=true");
    buildAndAssertSuccess();
    assertContainsEvent("experimental_builtins_dummy :: True");
  }

  @Test
  public void builtinsCanSeeFlags_doesNotExist() throws Exception {
    writeExportsBzl(
        // We use a None default here, but note that that's brittle if any machinery explicitly sets
        // flags to their default values. In practice the flag's real default value should be used.
        "print('experimental_does_not_exist :: %s' % ",
        "      _builtins.get_flag('experimental_does_not_exist', None))",
        "exported_toplevels = {}", //
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    buildAndAssertSuccess();
    assertContainsEvent("experimental_does_not_exist :: None");
  }

  @Test
  public void flagGuardedSymbol_canExportEvenWhenDisabled() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {'flag_guarded_symbol': 'overridden value'}",
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    // Default value of --experimental_builtins_dummy is false.
    buildAndAssertSuccess();
  }

  @Test
  public void flagGuardedSymbol_cannotUseWhenDisabledEvenIfInjected() throws Exception {
    // Implementation note: Flag guarding is implemented at name resolution time, before builtins
    // injection is applied.
    writeExportsBzl(
        "exported_toplevels = {'flag_guarded_symbol': 'overridden value'}",
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl("print('flag_guarded_symbol :: %s' % flag_guarded_symbol)");

    buildAndAssertFailure();
    assertContainsEvent("flag_guarded_symbol is experimental");
  }

  @Test
  public void flagGuardedSymbol_injectedValueIsSeenWhenFlagIsEnabled() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {'flag_guarded_symbol': 'overridden value'}",
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl("print('flag_guarded_symbol :: %s' % flag_guarded_symbol)");

    setBuildLanguageOptionsWithBuiltinsStaging("--experimental_builtins_dummy=true");
    buildAndAssertSuccess();
    assertContainsEvent("flag_guarded_symbol :: overridden value");
  }

  @Test
  public void flagGuardedSymbol_unconditionallyAccessibleToBuiltins() throws Exception {
    writeExportsBzl(
        "print('flag_guarded_symbol :: %s' % _builtins.toplevel.flag_guarded_symbol)",
        "exported_toplevels = {}", //
        "exported_rules = {}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    buildAndAssertSuccess();
    assertContainsEvent("flag_guarded_symbol :: original_value");
  }

  @Test
  public void nativeRulesCanUseSymbolsFromBuiltins() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {}",
        "exported_rules = {}",
        "exported_to_java = {'builtins_defined_symbol': 'value_from_builtins'}");
    scratch.file(
        "pkg/BUILD", //
        "sandwich_rule(name = 'sandwich')");

    getConfiguredTarget("//pkg:sandwich");
    assertContainsEvent("builtins_defined_symbol :: value_from_builtins");
  }

  @Test
  public void nativeRuleFailsToFindUnknownBuiltin() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {}", //
        "exported_rules = {}",
        "exported_to_java = {}");
    scratch.file(
        "pkg/BUILD", //
        "sandwich_rule(name = 'sandwich')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//pkg:sandwich");
    assertContainsEvent("(Internal error) No symbol named 'builtins_defined_symbol'");
  }

  // TODO(#11437): Verify whether this works for native-defined aspects as well.

  @Test
  public void nativeRulesCanCallFunctionsDefinedInBuiltins() throws Exception {
    writeExportsBzl(
        // The driver rule calls this helper twice with a list.
        "def func(arg):",
        "  print('got arg %s' % arg)",
        "  arg.append('blah')",
        "  return len(arg)",
        "exported_toplevels = {}",
        "exported_rules = {}",
        "exported_to_java = {'builtins_defined_logic': func}");
    scratch.file(
        "pkg/BUILD", //
        "sandwich_logic_rule(name = 'sandwich_logic')");

    getConfiguredTarget("//pkg:sandwich_logic");
    assertContainsEvent("got arg []");
    assertContainsEvent("builtins_defined_logic call 1 :: 1");
    assertContainsEvent("got arg [\"blah\"]");
    assertContainsEvent("builtins_defined_logic call 2 :: 2");
    assertContainsEvent("final list value :: [\"blah\", \"blah\"]");
  }

  @Test
  public void nativeRulesCanPassCtxToBuiltinsDefinedHelpers() throws Exception {
    writeExportsBzl(
        "def impl_helper(ctx):",
        "  ctx.actions.write(output=ctx.outputs.out, content=ctx.attr.content)",
        "exported_toplevels = {}",
        "exported_rules = {}",
        "exported_to_java = {'builtins_rule_impl_helper': impl_helper}");
    scratch.file(
        "pkg/BUILD", //
        "sandwich_ctx_rule(name = 'sandwich_ctx', content='foo', out='bar.txt')");

    ConfiguredTarget target = getConfiguredTarget("//pkg:sandwich_ctx");
    Artifact output = getBinArtifact("bar.txt", target);
    ActionAnalysisMetadata action = getGeneratingAction(output);
    assertThat(action).isInstanceOf(FileWriteAction.class);
    assertThat(((FileWriteAction) action).getFileContents()).isEqualTo("foo");
  }

  @Test
  public void nativeRulesCanDisplayUsefulStarlarkStackTrace() throws Exception {
    writeExportsBzl(
        // The driver rule calls this helper twice with a list. Doesn't matter, we fail immediately.
        "def func(arg):",
        "  1//0",
        "exported_toplevels = {}",
        "exported_rules = {}",
        "exported_to_java = {'builtins_defined_logic': func}");
    scratch.file(
        "pkg/BUILD", //
        "sandwich_logic_rule(name = 'sandwich_logic')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//pkg:sandwich_logic");
    // Rule implementation uses callStarlarkOrThrowRuleError(), which includes the stack trace.
    assertContainsEvent("line 2, column 4, in func");
    assertContainsEvent("Error: integer division by zero");
  }

  // The following tests check the integration of the injection override flag with builtins
  // injection. See BazelStarlarkEnvironmentTest for more detailed unit tests about the semantics of
  // this flag.

  @Test
  public void perSymbolInjectionOverride() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {'-overridable_symbol': 'new_value'}",
        "exported_rules = {'-overridable_rule': 'new_rule'}",
        "exported_to_java = {}");
    writePkgBuild("print('In BUILD: overridable_rule :: %s' % overridable_rule)");
    writePkgBzl(
        "print('In bzl: overridable_symbol :: %s' % overridable_symbol)",
        "print('In bzl: overridable_rule :: %s' % native.overridable_rule)");

    setBuildLanguageOptionsWithBuiltinsStaging(
        "--experimental_builtins_injection_override=+overridable_symbol,+overridable_rule");
    buildAndAssertSuccess();
    assertContainsEvent("In bzl: overridable_symbol :: new_value");
    assertContainsEvent("In bzl: overridable_rule :: new_rule");
    assertContainsEvent("In BUILD: overridable_rule :: new_rule");
  }

  @Test
  public void perSymbolInjectionOverride_lastOccurrenceWins() throws Exception {
    writeExportsBzl(
        "exported_toplevels = {'-overridable_symbol': 'new_value'}",
        "exported_rules = {'-overridable_rule': 'new_rule'}",
        "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl(
        "print('In bzl: overridable_symbol :: %s' % overridable_symbol)",
        "print('In bzl: overridable_rule :: %s' % native.overridable_rule)");

    // Tests that the last use of foo determines whether it's +foo or -foo. Also tests that the flag
    // is allowMultiple, so that passing the second list doesn't just zero out the first list.
    setBuildLanguageOptionsWithBuiltinsStaging(
        "--experimental_builtins_injection_override="
            + "+overridable_rule,+overridable_symbol,-overridable_symbol",
        "--experimental_builtins_injection_override=+overridable_symbol");
    buildAndAssertSuccess();
    assertContainsEvent("In bzl: overridable_symbol :: new_value");
    assertContainsEvent("In bzl: overridable_rule :: new_rule");
  }

  @Test
  public void perSymbolInjectionOverride_invalidOverrideItem() throws Exception {
    writeExportsBzl("exported_toplevels = {}", "exported_rules = {}", "exported_to_java = {}");
    writePkgBuild();
    writePkgBzl();

    setBuildLanguageOptionsWithBuiltinsStaging("--experimental_builtins_injection_override=foo");
    buildAndAssertFailure();
    assertContainsEvent("Invalid injection override item: 'foo'");
  }

  /**
   * Tests for injection, under inlining of {@link BzlLoadFunction}.
   *
   * <p>See {@link BzlLoadFunction#computeInline} for an explanation of inlining.
   */
  @RunWith(JUnit4.class)
  public static class BuiltinsInjectionTestWithInlining extends BuiltinsInjectionTest {

    @Override
    protected boolean usesInliningBzlLoadFunction() {
      return true;
    }
  }
}
