// 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', 'feature_flag_setter', 'check_something')",
        "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'},",
        "  deps = [':some_dep'],",
        "  transitive_configs = [':fruit'],",
        ")",
        "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', 'feature_flag_setter', 'check_something')",
        "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'},",
        "  deps = [':some_dep'],",
        "  transitive_configs = [':fruit'],",
        ")",
        "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");
  }
}
