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

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 org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Starlark-integration Tests for the ConfigFeatureFlagTransitionFactory. */
@RunWith(JUnit4.class)
public final class StarlarkConfigFeatureFlagTransitionFactoryTest extends BuildViewTestCase {

  @Override
  protected ConfiguredRuleClassProvider createRuleClassProvider() {
    ConfiguredRuleClassProvider.Builder builder =
        new ConfiguredRuleClassProvider.Builder().addRuleDefinition(new FeatureFlagSetterRule());
    TestRuleClassProvider.addStandardRules(builder);
    return builder.build();
  }

  private void setupRulesBzl() throws Exception {
    scratch.file("rules/BUILD", "");
    scratch.file(
        "rules/rule.bzl",
        """
        def _blank_impl(ctx):
            return []

        def _check_impl(ctx):
            if ctx.attr.succeed:
                return []
            else:
                fail("Rule has failed intentionally.")

        feature_flag_setter = rule(
            attrs = {
                "flag_values": attr.label_keyed_string_dict(),
                "deps": attr.label_list(),
            },
            cfg = config_common.config_feature_flag_transition("flag_values"),
            implementation = _blank_impl,
        )
        check_something = rule(
            attrs = {
                "succeed": attr.bool(),
            },
            implementation = _check_impl,
        )
        """);
  }

  @Test
  public void setsFeatureFlagSuccessfully() throws Exception {
    setupRulesBzl();
    scratch.file(
        "foo/BUILD",
        """
        load("//rules:rule.bzl", "check_something", "feature_flag_setter")

        config_feature_flag(
            name = "fruit",
            allowed_values = [
                "orange",
                "apple",
                "lemon",
            ],
            default_value = "orange",
        )

        config_setting(
            name = "is_apple",
            flag_values = {":fruit": "apple"},
            transitive_configs = [":fruit"],
        )

        feature_flag_setter(
            name = "top",
            flag_values = {":fruit": "apple"},
            transitive_configs = [":fruit"],
            deps = [":some_dep"],
        )

        check_something(
            name = "some_dep",
            succeed = select({
                ":is_apple": True,
                "//conditions:default": False,
            }),
            transitive_configs = [":fruit"],
        )
        """);
    scratch.overwriteFile(
        "tools/allowlists/config_feature_flag/BUILD",
        """
        package_group(
            name = "config_feature_flag",
            packages = ["//foo/..."],
        )

        package_group(
            name = "config_feature_flag_setter",
            packages = ["//rules/..."],
        )
        """);
    assertThat(getConfiguredTarget("//foo:top")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void failsWhenFeatureFlagSuccessfullySetToBadValue() throws Exception {
    // This is mostly a test of the testing infrastructure itself.
    // Want to ensure check_something isn't spuriously passing for whatever reason.
    setupRulesBzl();
    scratch.file(
        "foo/BUILD",
        """
        load("//rules:rule.bzl", "check_something", "feature_flag_setter")

        config_feature_flag(
            name = "fruit",
            allowed_values = [
                "orange",
                "apple",
                "lemon",
            ],
            default_value = "orange",
        )

        config_setting(
            name = "is_apple",
            flag_values = {":fruit": "apple"},
            transitive_configs = [":fruit"],
        )

        feature_flag_setter(
            name = "top",
            flag_values = {":fruit": "orange"},
            transitive_configs = [":fruit"],
            deps = [":some_dep"],
        )

        check_something(
            name = "some_dep",
            succeed = select({
                ":is_apple": True,
                "//conditions:default": False,
            }),
            transitive_configs = [":fruit"],
        )
        """);
    scratch.overwriteFile(
        "tools/allowlists/config_feature_flag/BUILD",
        """
        package_group(
            name = "config_feature_flag",
            packages = ["//foo/..."],
        )

        package_group(
            name = "config_feature_flag_setter",
            packages = ["//rules/..."],
        )
        """);
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:top");
    assertContainsEvent("Error in fail: Rule has failed intentionally.");
  }

  @Test
  public void failsWhenInstanceNotInAllowlist() throws Exception {
    setupRulesBzl();
    scratch.file(
        "bar/BUILD",
        """
        config_feature_flag(
            name = "fruit",
            allowed_values = [
                "orange",
                "apple",
                "lemon",
            ],
            default_value = "orange",
        )
        """);
    scratch.file(
        "foo/BUILD",
        """
        load("//rules:rule.bzl", "feature_flag_setter")

        feature_flag_setter(
            name = "top",
            flag_values = {"//bar:fruit": "apple"},
            transitive_configs = ["//bar:fruit"],
        )
        """);
    scratch.overwriteFile(
        "tools/allowlists/config_feature_flag/BUILD",
        """
        package_group(
            name = "config_feature_flag",
            packages = ["//bar/..."],
        )

        package_group(
            name = "config_feature_flag_setter",
            packages = ["//rules/..."],
        )
        """);
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:top");
    assertContainsEvent("the attribute flag_values is not available in this package");
  }

  @Test
  public void failsWhenRuleClassNotInSetterAllowlist() throws Exception {
    setupRulesBzl();
    scratch.file(
        "foo/BUILD",
        """
        load("//rules:rule.bzl", "feature_flag_setter")

        config_feature_flag(
            name = "fruit",
            allowed_values = [
                "orange",
                "apple",
                "lemon",
            ],
            default_value = "orange",
        )

        feature_flag_setter(
            name = "top",
            flag_values = {":fruit": "apple"},
            transitive_configs = [":fruit"],
        )
        """);
    scratch.overwriteFile(
        "tools/allowlists/config_feature_flag/BUILD",
        """
        package_group(
            name = "config_feature_flag",
            packages = ["//foo/..."],
        )

        package_group(
            name = "config_feature_flag_setter",
            packages = [],
        )
        """);
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:top");
    assertContainsEvent("rule class is not allowed access to feature flags setter transition");
  }
}
