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

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

import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import java.util.HashMap;
import java.util.Map;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.StarlarkBuiltin;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkInt;
import net.starlark.java.eval.StarlarkList;
import net.starlark.java.eval.StarlarkValue;
import net.starlark.java.eval.Tuple;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@code native.existing_rule} and {@code native.existing_rules} functions.
 *
 * <p>This class covers the legacy behavior where the {@code
 * --incompatible_existing_rules_immutable_view} flag is disabled. The enabled case is covered by
 * the subclass, {@link WithImmutableView}.
 */
@RunWith(JUnit4.class)
public class NativeExistingRulesTest extends BuildViewTestCase {
  private TestStarlarkBuiltin testStarlarkBuiltin; // initialized by createRuleClassProvider()

  // Intended to be overridden by this test case's subclasses. Note that overriding of JUnit's
  // @Before methods is not recommended.
  protected void setupOptions() throws Exception {
    // --noincompatible_existing_rules_immutable_view is the default; set it explicitly for clarity.
    setBuildLanguageOptions("--noincompatible_existing_rules_immutable_view");
  }

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

  @StarlarkBuiltin(name = "test")
  private static final class TestStarlarkBuiltin implements StarlarkValue {

    private final Map<String, Object> saved = new HashMap<>();

    @StarlarkMethod(
        name = "save",
        parameters = {
          @Param(name = "name", doc = "Name under which to save the value"),
          @Param(name = "value", doc = "Value to save")
        },
        doc = "Saves a Starlark value for testing from Java")
    public synchronized void save(String name, Object value) {
      saved.put(name, value);
    }
  }

  @Override
  protected ConfiguredRuleClassProvider createRuleClassProvider() {
    ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
    TestRuleClassProvider.addStandardRules(builder);
    testStarlarkBuiltin = new TestStarlarkBuiltin();
    builder.addBzlToplevel("test", testStarlarkBuiltin);
    return builder.build();
  }

  private Object getSaved(String name) {
    return testStarlarkBuiltin.saved.get(name);
  }

  @Test
  public void existingRule_handlesSelect() throws Exception {
    scratch.file("test/starlark/BUILD");
    scratch.file(
        "test/starlark/rulestr.bzl", //
        "def rule_dict(name):",
        "  return native.existing_rule(name)");

    scratch.file(
        "test/getrule/BUILD",
        "load('//test/starlark:rulestr.bzl', 'rule_dict')",
        "cc_library(",
        "    name ='x',",
        "    srcs = select({'//conditions:default': []}),",
        ")",
        "rule_dict('x')");

    // Parse the BUILD file, to make sure select() makes it out of native.existing_rule().
    assertThat(getConfiguredTarget("//test/getrule:x")).isNotNull();
  }

  @Test
  public void existingRule_returnsNone() throws Exception {
    scratch.file(
        "test/rulestr.bzl",
        "def test_rule(name, x):",
        "  print(native.existing_rule(x))",
        "  if native.existing_rule(x) == None:",
        "    native.cc_library(name = name)");
    scratch.file(
        "test/BUILD",
        "load('//test:rulestr.bzl', 'test_rule')",
        "test_rule('a', 'does not exist')",
        "test_rule('b', 'BUILD')"); // exists, but as a target and not a rule

    assertThat(getConfiguredTarget("//test:a")).isNotNull();
    assertThat(getConfiguredTarget("//test:b")).isNotNull();
  }

  @Test
  public void existingRule_roundTripsSelect() throws Exception {
    scratch.file(
        "test/existing_rule.bzl",
        "def macro():",
        "  s = select({'//foo': ['//bar']})",
        "  print('Passed: ' + repr(s))",
        "  native.cc_library(name = 'x', srcs = s)",
        "  print('Returned: ' + repr(native.existing_rule('x')['srcs']))",
        // The value returned here should round-trip fine.
        "  native.cc_library(name = 'y', srcs = native.existing_rule('x')['srcs'])");
    scratch.file(
        "test/BUILD",
        "load('//test:existing_rule.bzl', 'macro')",
        "macro()",
        "cc_library(name = 'a', srcs = [])");
    getConfiguredTarget("//test:a");
    assertContainsEvent("Passed: select({\"//foo\": [\"//bar\"]}");
    // The short labels are now in their canonical form, and the sequence is represented as
    // tuple instead of list, but the meaning is unchanged.
    assertContainsEvent("Returned: select({\"//foo:foo\": (\"//bar:bar\",)}");
  }

  @Test
  public void existingRule_shortensLabelsInSamePackage() throws Exception {
    scratch.file(
        "test/existing_rule.bzl",
        "def save_deps():",
        "  r = native.existing_rule('b')",
        "  test.save(\"r['deps']\", r['deps'])");
    scratch.file(
        "test/BUILD",
        "load('//test:existing_rule.bzl', 'save_deps')",
        "cc_library(name = 'a', srcs = [])",
        "cc_binary(name = 'b', deps = ['//test:a'])",
        "save_deps()");
    getConfiguredTarget("//test:b");
    assertThat(Starlark.toIterable(getSaved("r['deps']")))
        .containsExactly(":a"); // as opposed to "//test:a"
  }

  @Test
  public void existingRules_findsRulesAndAttributes() throws Exception {
    scratch.file("test/BUILD");
    scratch.file("test/starlark/BUILD");
    scratch.file(
        "test/starlark/rulestr.bzl",
        "def rule_dict(name):",
        "  return native.existing_rule(name)",
        "def rules_dict():",
        "  return native.existing_rules()",
        "def nop(ctx):",
        "  pass",
        "nop_rule = rule(attrs = {'x': attr.label()}, implementation = nop)",
        "def test_save(name, value):",
        "  test.save(name, value)");

    scratch.file(
        "test/getrule/BUILD",
        "load('//test/starlark:rulestr.bzl', 'rules_dict', 'rule_dict', 'nop_rule', 'test_save')",
        "genrule(name = 'a', outs = ['a.txt'], ",
        "        licenses = ['notice'],",
        "        output_to_bindir = False,",
        "        tools = [ '//test:bla' ], cmd = 'touch $@')",
        "nop_rule(name = 'c', x = ':a')",
        "rlist = rules_dict()",
        "test_save('all_str', [rlist['a']['kind'], rlist['a']['name'],",
        "                      rlist['c']['kind'], rlist['c']['name']])",
        "adict = rule_dict('a')",
        "cdict = rule_dict('c')",
        "test_save('a_str', [adict['kind'], adict['name'], adict['outs'][0], adict['tools'][0]])",
        "test_save('c_str', [cdict['kind'], cdict['name'], cdict['x']])",
        "test_save('adict.keys()', adict.keys())");

    getConfiguredTarget("//test/getrule:BUILD");
    assertThat(Starlark.toIterable(getSaved("all_str")))
        .containsExactly("genrule", "a", "nop_rule", "c")
        .inOrder();
    assertThat(Starlark.toIterable(getSaved("a_str")))
        .containsExactly("genrule", "a", ":a.txt", "//test:bla")
        .inOrder();
    assertThat(Starlark.toIterable(getSaved("c_str")))
        .containsExactly("nop_rule", "c", ":a")
        .inOrder();
    assertThat(Starlark.toIterable(getSaved("adict.keys()")))
        .containsAtLeast(
            "name",
            "visibility",
            "transitive_configs",
            "tags",
            "generator_name",
            "generator_function",
            "generator_location",
            "features",
            "compatible_with",
            "target_compatible_with",
            "restricted_to",
            "srcs",
            "tools",
            "toolchains",
            "outs",
            "cmd",
            "output_to_bindir",
            "local",
            "message",
            "executable",
            "stamp",
            "heuristic_label_expansion",
            "kind");
  }

  @Test
  public void existingRule_ignoresHiddenAttributes() throws Exception {
    scratch.file(
        "test/inc.bzl", //
        "def _check_hidden_attr_exists(ctx):",
        "    if ctx.attr._hidden_attr != 'hidden_val':",
        "        fail('ctx.attr._hidden_attr != \"hidden_val\"')",
        "    pass",
        "my_rule = rule(",
        "    attrs = {",
        "        '_hidden_attr': attr.string(default = 'hidden_val'),",
        "        'normal_attr': attr.string(default = 'normal_val'),",
        "    },",
        "    implementation = _check_hidden_attr_exists",
        ")",
        "def f():",
        "    my_rule(name = 'rulename')",
        "    r = native.existing_rule('rulename')",
        "    test.save('r.keys()', r.keys())",
        "    test.save('r.values()', r.values())",
        "    test.save('\"_hidden_attr\" in r', \"_hidden_attr\" in r)");
    scratch.file(
        "test/BUILD",
        "load('inc.bzl', 'f')", //
        "f()");

    assertThat(getConfiguredTarget("//test:rulename")).isNotNull();
    assertThat(Starlark.toIterable(getSaved("r.keys()")))
        .containsAtLeast("name", "kind", "normal_attr");
    assertThat(Starlark.toIterable(getSaved("r.keys()"))).doesNotContain("_hidden_attr");
    assertThat(Starlark.toIterable(getSaved("r.values()")))
        .containsAtLeast("rulename", "my_rule", "normal_val");
    assertThat(Starlark.toIterable(getSaved("r.values()"))).doesNotContain("hidden_val");
    assertThat((Boolean) getSaved("\"_hidden_attr\" in r")).isFalse();
  }

  @Test
  public void existingRule_returnsObjectWithCorrectMutability() throws Exception {
    scratch.file(
        "test/BUILD",
        "load('inc.bzl', 'f')", //
        "f()");
    scratch.file(
        "test/inc.bzl", //
        "def f():",
        "  native.config_setting(name='x', define_values={'key': 'value'})",
        "  r = native.existing_rule('x')",
        "  r['no_such_attribute'] = 'foo'",
        "  r['define_values']['key'] = 123"); // mutate the dict

    assertThat(getConfiguredTarget("//test:BUILD")).isNotNull(); // no error on mutation
  }

  @Test
  public void existingRule_returnsDictLikeObject() throws Exception {
    scratch.file(
        "test/BUILD",
        "load('inc.bzl', 'f')", //
        "f()");
    scratch.file(
        "test/inc.bzl", //
        "def f():",
        "  native.config_setting(name='x', define_values={'key': 'value'})",
        "  r = native.existing_rule('x')",
        "  print('r == %s' % repr(r))",
        "  test.save('[key for key in r]', [key for key in r])",
        "  test.save('list(r)', list(r))",
        "  test.save('r.keys()', r.keys())",
        "  test.save('r.values()', r.values())",
        "  test.save('r.items()', r.items())",
        "  test.save(\"r['define_values']\", r['define_values'])",
        "  test.save(\"r.get('define_values', 123)\", r.get('define_values', 123))",
        "  test.save(\"r.get('invalid_attr', 123)\", r.get('invalid_attr', 123))",
        "  test.save(\"'define_values' in r\", 'define_values' in r)",
        "  test.save(\"'invalid_attr' in r\", 'invalid_attr' in r)");

    Dict<?, ?> expectedDefineValues = Dict.builder().put("key", "value").buildImmutable();
    assertThat(getConfiguredTarget("//test:BUILD")).isNotNull(); // no error
    assertThat(Starlark.toIterable(getSaved("[key for key in r]")))
        .containsAtLeast("define_values", "name", "kind");
    assertThat(Starlark.toIterable(getSaved("list(r)")))
        .containsAtLeast("define_values", "name", "kind");
    assertThat(Starlark.toIterable(getSaved("r.keys()")))
        .containsAtLeast("define_values", "name", "kind");
    assertThat(Starlark.toIterable(getSaved("r.values()")))
        .containsAtLeast(expectedDefineValues, "x", "config_setting");
    assertThat(Starlark.toIterable(getSaved("r.items()")))
        .containsAtLeast(
            Tuple.of("define_values", expectedDefineValues),
            Tuple.of("name", "x"),
            Tuple.of("kind", "config_setting"));
    assertThat(getSaved("r['define_values']")).isEqualTo(expectedDefineValues);
    assertThat(getSaved("r.get('define_values', 123)")).isEqualTo(expectedDefineValues);
    assertThat(getSaved("r.get('invalid_attr', 123)")).isEqualTo(StarlarkInt.of(123));
    assertThat(getSaved("'define_values' in r")).isEqualTo(true);
    assertThat(getSaved("'invalid_attr' in r")).isEqualTo(false);
  }

  @Test
  public void existingRule_asDictArgument() throws Exception {
    scratch.file(
        "test/test.bzl",
        "def save_as_dict(r):",
        "  test.save('type(dict(r))', type(dict(r)))",
        "  test.save('dict(r)[\"name\"]', dict(r)[\"name\"])",
        "  test.save('dict(r)[\"kind\"]', dict(r)[\"kind\"])");
    scratch.file(
        "test/BUILD",
        "load('//test:test.bzl', 'save_as_dict')", //
        "cc_library(",
        "    name ='rulename',",
        ")",
        "save_as_dict(existing_rule('rulename'))");
    getConfiguredTarget("//test:rulename");
    assertThat(getSaved("type(dict(r))")).isEqualTo("dict");
    assertThat(getSaved("dict(r)[\"name\"]")).isEqualTo("rulename");
    assertThat(getSaved("dict(r)[\"kind\"]")).isEqualTo("cc_library");
  }

  @Test
  public void existingRule_asDictUpdateArgument() throws Exception {
    // We do not test `existing_rule(r).update({...})` because `existing_rule(r)` may be immutable
    // (as verified by other test cases).
    scratch.file(
        "test/test.bzl",
        "def save_as_updated_dict(r):",
        "  updated_dict = {'name': 'dictname', 'dictkey': 1}",
        "  updated_dict.update(r)",
        "  test.save('updated_dict[\"name\"]', updated_dict[\"name\"])",
        "  test.save('updated_dict[\"kind\"]', updated_dict[\"kind\"])",
        "  test.save('updated_dict[\"dictkey\"]', updated_dict[\"dictkey\"])");
    scratch.file(
        "test/BUILD",
        "load('//test:test.bzl', 'save_as_updated_dict')", //
        "cc_library(",
        "    name ='rulename',",
        ")",
        "save_as_updated_dict(existing_rule('rulename'))");
    getConfiguredTarget("//test:rulename");
    assertThat(getSaved("updated_dict[\"name\"]")).isEqualTo("rulename");
    assertThat(getSaved("updated_dict[\"kind\"]")).isEqualTo("cc_library");
    assertThat(getSaved("updated_dict[\"dictkey\"]")).isEqualTo(StarlarkInt.of(1));
  }

  @Test
  public void existingRule_unionableWithDict() throws Exception {
    scratch.file(
        "test/test.bzl",
        "def save_as_union(dict_val, r):",
        "  test.save('dict_val | r', dict_val | r)",
        "  test.save('r | dict_val', r | dict_val)",
        "  dict_val |= r",
        "  test.save('dict_val |= r', dict_val)");
    scratch.file(
        "test/BUILD",
        "load('//test:test.bzl', 'save_as_union')",
        "cc_library(",
        "    name ='rulename',",
        ")",
        "save_as_union({'name': 'dictname', 'dictkey': 1}, existing_rule('rulename'))");
    getConfiguredTarget("//test:rulename");
    Map<String, Object> unionDictWithExistingRule =
        Dict.cast(getSaved("dict_val | r"), String.class, Object.class, "dict_val | r");
    assertThat(unionDictWithExistingRule)
        .containsAtLeast("name", "rulename", "dictkey", StarlarkInt.of(1), "kind", "cc_library");
    Map<String, Object> unionExistingRuleWithDict =
        Dict.cast(getSaved("r | dict_val"), String.class, Object.class, "r | dict_val");
    assertThat(unionExistingRuleWithDict)
        .containsAtLeast("name", "dictname", "dictkey", StarlarkInt.of(1), "kind", "cc_library");
    Map<String, Object> inPlaceUnionDictWithExistingRule =
        Dict.cast(getSaved("dict_val |= r"), String.class, Object.class, "dict_val | r");
    assertThat(inPlaceUnionDictWithExistingRule)
        .containsAtLeast("name", "rulename", "dictkey", StarlarkInt.of(1), "kind", "cc_library");
  }

  @Test
  public void existingRule_asKwargs() throws Exception {
    scratch.file(
        "test/test.bzl",
        "def save_kwargs(**kwargs):",
        "  test.save('kwargs[\"name\"]', kwargs[\"name\"])",
        "  test.save('kwargs[\"kind\"]', kwargs[\"kind\"])",
        "def save_kwargs_of_existing_rule(name):",
        "  save_kwargs(**native.existing_rule(name))");
    scratch.file(
        "test/BUILD",
        "load('//test:test.bzl', 'save_kwargs_of_existing_rule')", //
        "cc_library(",
        "    name ='rulename',",
        ")",
        "save_kwargs_of_existing_rule('rulename')");
    getConfiguredTarget("//test:rulename");
    assertThat(getSaved("kwargs[\"name\"]")).isEqualTo("rulename");
    assertThat(getSaved("kwargs[\"kind\"]")).isEqualTo("cc_library");
  }

  // Regression test for https://github.com/bazelbuild/bazel/issues/16256
  @Test
  public void existingRule_encodesToJson() throws Exception {
    // We need a Starlark rule - native rules can have attribute values that the json encoder
    // doesn't handle.
    scratch.file(
        "test/test.bzl",
        "def _dummy_impl(ctx):",
        "  pass",
        "test_library = rule(",
        "  implementation = _dummy_impl,",
        "  attrs = {'srcs': attr.label_list(allow_files = True)},",
        ")",
        // TODO(b/249397668): simplifying this to `json_encode = json.encode` etc. causes a
        // NoCodecException. Need to investigate.
        "def json_encode(value):",
        "  return json.encode(value)",
        "def json_decode(text):",
        "  return json.decode(text)",
        "def save(name, object):",
        "  test.save(name, object)");
    scratch.file(
        "test/BUILD",
        "load('//test:test.bzl', 'test_library', 'json_decode', 'json_encode', 'save')", //
        "test_library(",
        "    name ='foo',",
        "    srcs = ['foo.cc'],",
        ")",
        "save('foo', json_decode(json_encode(existing_rule('foo'))))");
    scratch.file("test/foo.cc");
    getConfiguredTarget("//test:foo");
    // We test a subset of attributes after an encode-decode round trip because the rule also has
    // default attributes with default values, which will get encoded to json and which will change
    // whenever default attributes get introduced, making string comparison of encoded json fragile.
    Map<String, Object> jsonRoundTripValue =
        Dict.cast(
            getSaved("foo"), String.class, Object.class, "json round trip of existing_rule('foo')");
    assertThat(jsonRoundTripValue)
        .containsAtLeast(
            "name", "foo", "kind", "test_library", "srcs", StarlarkList.immutableOf(":foo.cc"));
  }

  @Test
  public void existingRules_returnsObjectWithCorrectMutability() throws Exception {
    scratch.file(
        "test/BUILD",
        "load('inc.bzl', 'f')", //
        "f()");
    scratch.file(
        "test/inc.bzl", //
        "def f():",
        "  native.config_setting(name='x', define_values={'key': 'value'})",
        "  rs = native.existing_rules()",
        "  rs['no_such_rule'] = {'name': 'no_such_rule', 'kind': 'config_setting'}"); // mutate

    assertThat(getConfiguredTarget("//test:BUILD")).isNotNull(); // no error on mutation
  }

  @Test
  public void existingRules_returnsDictLikeObject() throws Exception {
    scratch.file(
        "test/BUILD",
        "load('inc.bzl', 'f')", //
        "f()");
    scratch.file(
        "test/inc.bzl", //
        "def f():",
        "  native.config_setting(name='x', define_values={'key_x': 'value_x'})",
        "  native.config_setting(name='y', define_values={'key_y': 'value_y'})",
        "  rs = native.existing_rules()",
        "  print('rs == %s' % repr(rs))",
        "  test.save('[key for key in rs]', [key for key in rs])",
        "  test.save('list(rs)', list(rs))",
        "  test.save('rs.keys()', rs.keys())",
        "  test.save(\"[v['name'] for v in rs.values()]\", [v['name'] for v in rs.values()])",
        "  test.save(\"[(i[0], i[1]['name']) for i in rs.items()]\", [(i[0], i[1]['name']) for i in"
            + " rs.items()])",
        "  test.save(\"rs['x']['define_values']\", rs['x']['define_values'])",
        "  test.save(\"rs.get('x', {'name': 'z'})['name']\", rs.get('x', {'name': 'z'})['name'])",
        "  test.save(\"rs.get('invalid_rule', {'name': 'invalid_rule'})\", rs.get('invalid_rule',"
            + " {'name': 'invalid_rule'}))",
        "  test.save(\"'x' in rs\", 'x' in rs)",
        "  test.save(\"'invalid_rule' in rs\", 'invalid_rule' in rs)");

    assertThat(getConfiguredTarget("//test:BUILD")).isNotNull(); // no error
    assertThat(Starlark.toIterable(getSaved("[key for key in rs]"))).containsExactly("x", "y");
    assertThat(Starlark.toIterable(getSaved("list(rs)"))).containsExactly("x", "y");
    assertThat(Starlark.toIterable(getSaved("rs.keys()"))).containsExactly("x", "y");
    assertThat(Starlark.toIterable(getSaved("[v['name'] for v in rs.values()]")))
        .containsExactly("x", "y");
    assertThat(Starlark.toIterable(getSaved("[(i[0], i[1]['name']) for i in rs.items()]")))
        .containsExactly(Tuple.of("x", "x"), Tuple.of("y", "y"));
    assertThat(getSaved("rs['x']['define_values']"))
        .isEqualTo(Dict.builder().put("key_x", "value_x").buildImmutable());
    assertThat(getSaved("rs.get('x', {'name': 'z'})['name']")).isEqualTo("x");
    assertThat(getSaved("rs.get('invalid_rule', {'name': 'invalid_rule'})"))
        .isEqualTo(Dict.builder().put("name", "invalid_rule").buildImmutable());
    assertThat(getSaved("'x' in rs")).isEqualTo(true);
    assertThat(getSaved("'invalid_rule' in rs")).isEqualTo(false);
  }

  @Test
  public void existingRules_returnsSnapshotOfOnlyRulesInstantiatedUpToThatPoint() throws Exception {
    scratch.file(
        "test/BUILD",
        "load('inc.bzl', 'f')", //
        "f()");
    scratch.file(
        "test/inc.bzl", //
        "def f():",
        "  native.config_setting(name='x', define_values={'key_x': 'value_x'})",
        "  rs1 = native.existing_rules()",
        "  native.config_setting(name='y', define_values={'key_y': 'value_y'})",
        "  rs2 = native.existing_rules()",
        "  native.config_setting(name='z', define_values={'key_z': 'value_z'})",
        "  rs3 = native.existing_rules()",
        "  test.save('rs1.keys()', rs1.keys())",
        "  test.save('rs2.keys()', rs2.keys())",
        "  test.save('rs3.keys()', rs3.keys())");

    assertThat(getConfiguredTarget("//test:BUILD")).isNotNull(); // no error
    assertThat(Starlark.toIterable(getSaved("rs1.keys()"))).containsExactly("x");
    assertThat(Starlark.toIterable(getSaved("rs2.keys()"))).containsExactly("x", "y");
    assertThat(Starlark.toIterable(getSaved("rs3.keys()"))).containsExactly("x", "y", "z");
  }

  // Regression test for https://github.com/bazelbuild/bazel/issues/16256
  @Test
  public void existingRules_encodeToJson() throws Exception {
    // We need a Starlark rule - native rules can have attribute values that the json encoder
    // doesn't handle.
    scratch.file(
        "test/test.bzl",
        "def _dummy_impl(ctx):",
        "  pass",
        "test_library = rule(",
        "  implementation = _dummy_impl,",
        "  attrs = {'srcs': attr.label_list(allow_files = True)},",
        ")",
        // TODO(b/249397668): simplifying this to `json_encode = json.encode` etc. causes a
        // NoCodecException. Need to investigate.
        "def json_encode(value):",
        "  return json.encode(value)",
        "def json_decode(text):",
        "  return json.decode(text)",
        "def save(name, object):",
        "  test.save(name, object)");
    scratch.file(
        "test/BUILD",
        "load('//test:test.bzl', 'test_library', 'json_decode', 'json_encode', 'save')", //
        "test_library(",
        "    name ='foo',",
        "    srcs = ['foo.cc'],",
        ")",
        "test_library(",
        "    name ='bar',",
        "    srcs = ['bar.cc'],",
        ")",
        "save('rules', json_decode(json_encode(existing_rules())))");
    scratch.file("test/foo.cc");
    getConfiguredTarget("//test:bar");
    // We test a subset of attributes after an encode-decode round trip because the rule also has
    // default attributes with default values, which will get encoded to json and which will change
    // whenever default attributes get introduced, making string comparison of encoded json fragile.
    Dict<String, Object> jsonRoundTripRulesValue =
        Dict.cast(
            getSaved("rules"), String.class, Object.class, "json round trip of `existing_rules()`");
    assertThat(jsonRoundTripRulesValue.keySet()).containsExactly("foo", "bar");
    Map<String, Object> jsonRoundTripFooValue =
        Dict.cast(
            jsonRoundTripRulesValue.get("foo"),
            String.class,
            Object.class,
            "json round trip of `existing_rule('foo')`");
    assertThat(jsonRoundTripFooValue)
        .containsAtLeast(
            "name", "foo", "kind", "test_library", "srcs", StarlarkList.immutableOf(":foo.cc"));
    Map<String, Object> jsonRoundTripBarValue =
        Dict.cast(
            jsonRoundTripRulesValue.get("bar"),
            String.class,
            Object.class,
            "json round trip of `existing_rule('bar')`");
    assertThat(jsonRoundTripBarValue)
        .containsAtLeast(
            "name", "bar", "kind", "test_library", "srcs", StarlarkList.immutableOf(":bar.cc"));
  }

  /**
   * Tests for {@code native.existing_rule} and {@code native.existing_rules} Starlark functions
   * with the {@code --incompatible_existing_rules_immutable_view} flag set.
   */
  @RunWith(JUnit4.class)
  public static final class WithImmutableView extends NativeExistingRulesTest {

    @Override
    protected void setupOptions() throws Exception {
      setBuildLanguageOptions("--incompatible_existing_rules_immutable_view");
    }

    @Test
    @Override
    public void existingRule_returnsObjectWithCorrectMutability() throws Exception {
      scratch.file(
          "test/BUILD",
          "load('inc.bzl', 'f')", //
          "f()");
      scratch.file(
          "test/inc.bzl", //
          "def f():",
          "  native.config_setting(name='x', define_values={'key': 'value'})",
          "  r = native.existing_rule('x')",
          "  r['no_such_attribute'] = 123"); // mutate the view

      reporter.removeHandler(failFastHandler);
      assertThat(getConfiguredTarget("//test:BUILD")).isNull(); // mutation fails
      assertContainsEvent("can only assign an element in a dictionary or a list");
    }

    @Test
    @Override
    public void existingRules_returnsObjectWithCorrectMutability() throws Exception {
      scratch.file(
          "test/BUILD",
          "load('inc.bzl', 'f')", //
          "f()");
      scratch.file(
          "test/inc.bzl", //
          "def f():",
          "  native.config_setting(name='x', define_values={'key': 'value'})",
          "  rs = native.existing_rules()",
          "  rs['no_such_rule'] = {'name': 'no_such_rule', 'kind': 'config_setting'}"); // mutate

      reporter.removeHandler(failFastHandler);
      assertThat(getConfiguredTarget("//test:BUILD")).isNull(); // mutation fails
      assertContainsEvent("can only assign an element in a dictionary or a list");
    }

    @Test
    public void existingRules_returnsDeeplyImmutableView() throws Exception {
      scratch.file(
          "test/BUILD",
          "load('inc.bzl', 'f')", //
          "f()");
      scratch.file(
          "test/inc.bzl", //
          "def f():",
          "  native.config_setting(name='x', define_values={'key': 'value'})",
          "  rs = native.existing_rules()",
          "  rs['x']['define_values']['key'] = 123"); // mutate an attribute value within the view

      reporter.removeHandler(failFastHandler);
      assertThat(getConfiguredTarget("//test:BUILD")).isNull();
      assertContainsEvent("trying to mutate a frozen dict value");
    }
  }
}
