// Copyright 2023 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.analysis;

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

import com.google.common.collect.ObjectArrays;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.analysis.starlark.StarlarkExecGroupCollection;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.StarlarkInfo;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Test for aspect automatic exec groups. */
@RunWith(TestParameterInjector.class)
public class AspectAutoExecGroupsTest extends BuildViewTestCase {
  /**
   * Sets up two toolchains types, each with a single toolchain implementation and a single
   * exec_compatible_with platform.
   *
   * <p>toolchain_type_1 -> foo_toolchain -> exec_compatible_with platform_1 toolchain_type_2 ->
   * bar_toolchain -> exec_compatible_with platform_2
   */
  @Before
  public void createToolchainsAndPlatforms() throws Exception {
    scratch.file(
        "rule/test_toolchain.bzl",
        "def _impl(ctx):",
        "    return [platform_common.ToolchainInfo(",
        "      tool = ctx.executable._tool,",
        "      files_to_run = ctx.attr._tool[DefaultInfo].files_to_run,",
        "    )]",
        "test_toolchain = rule(",
        "    implementation = _impl,",
        "    attrs = {",
        "       '_tool': attr.label(default='//toolchain:b_tool', executable=True, cfg='exec'),",
        "    },",
        ")");
    scratch.file(
        "rule/BUILD",
        "exports_files(['test_toolchain/bzl'])",
        "toolchain_type(name = 'toolchain_type_1')",
        "toolchain_type(name = 'toolchain_type_2')");
    scratch.file(
        "toolchain/BUILD",
        "load('//rule:test_toolchain.bzl', 'test_toolchain')",
        "genrule(name = 'a_tool', outs = ['atool'], cmd = '', executable = True)",
        "genrule(name = 'b_tool', outs = ['btool'], cmd = '', executable = True)",
        "test_toolchain(",
        "    name = 'foo',",
        ")",
        "toolchain(",
        "    name = 'foo_toolchain',",
        "    toolchain_type = '//rule:toolchain_type_1',",
        "    target_compatible_with = ['//platforms:constraint_1'],",
        "    exec_compatible_with = ['//platforms:constraint_1'],",
        "    toolchain = ':foo',",
        ")",
        "test_toolchain(",
        "    name = 'bar',",
        ")",
        "toolchain(",
        "    name = 'bar_toolchain',",
        "    toolchain_type = '//rule:toolchain_type_2',",
        "    target_compatible_with = ['//platforms:constraint_1'],",
        "    exec_compatible_with = ['//platforms:constraint_2'],",
        "    toolchain = ':bar',",
        ")");

    scratch.file(
        "platforms/BUILD",
        "constraint_setting(name = 'setting')",
        "constraint_value(",
        "    name = 'constraint_1',",
        "    constraint_setting = ':setting',",
        ")",
        "constraint_value(",
        "    name = 'constraint_2',",
        "    constraint_setting = ':setting',",
        ")",
        "platform(",
        "    name = 'platform_1',",
        "    constraint_values = [':constraint_1'],",
        ")",
        "platform(",
        "    name = 'platform_2',",
        "    constraint_values = [':constraint_2'],",
        "    exec_properties = {",
        "        'watermelon.ripeness': 'unripe',",
        "        'watermelon.color': 'red',",
        "    },",
        ")");
  }

  @Before
  public void setup() throws Exception {
    useConfiguration();
  }

  @Override
  public void useConfiguration(String... args) throws Exception {
    String[] flags = {
      "--extra_toolchains=//toolchain:foo_toolchain,//toolchain:bar_toolchain",
      "--platforms=//platforms:platform_1",
      "--extra_execution_platforms=//platforms:platform_1,//platforms:platform_2"
    };

    super.useConfiguration(ObjectArrays.concat(flags, args, String.class));
  }

  /**
   * Creates custom rule which produces action with {@code actionParameters}, adds {@code
   * extraAttributes}, defines {@code toolchains}, and adds custom exec groups from {@code
   * execGroups}. Depending on {@code actionRunCommand} parameter, {@code actions.run} or {@code
   * actions.run_shell} is created. This rule also defines an aspect on its {@code deps} attribute.
   */
  private void createCustomRule(
      String action,
      String actionParameters,
      String extraAttributes,
      String toolchains,
      String execGroups)
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "load('//test:aspect.bzl', 'custom_aspect')",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file(ctx.label.name + '_dummy_output.jar')",
        "  " + action + "(",
        actionParameters,
        "    outputs = [output_jar],",
        action.equals("ctx.actions.run")
            ? (actionParameters.contains("executable =") // avoid adding executable parameter twice
                ? ""
                : "executable = ctx.toolchains['//rule:toolchain_type_1'].tool,")
            : "    command = 'echo',",
        "  )",
        "  return [DefaultInfo(files = depset([output_jar]))]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    '_tool': attr.label(default = '//toolchain:a_tool', cfg = 'exec', executable = True),",
        "    'deps': attr.label_list(aspects = [custom_aspect]),",
        extraAttributes,
        "  },",
        "  exec_groups = {",
        execGroups,
        "  },",
        "  toolchains = " + toolchains + ",",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_dep')",
        "custom_rule(name = 'custom_rule_name', deps= ['custom_rule_dep'])");
  }

  /**
   * Creates custom aspect which produces action with `{@code actionParameters}, adds {@code
   * extraAttributes}, defines {@code toolchains}, and adds custom exec groups from {@code
   * execGroups}. Depending on {@code actionRunCommand} parameter, {@code actions.run} or {@code
   * actions.run_shell} is created.
   */
  private void createCustomAspect(
      String action,
      String actionParameters,
      String extraAttributes,
      String toolchains,
      String execGroups)
      throws Exception {
    scratch.file(
        "test/aspect.bzl",
        "OutputFile = provider(fields = {'file': 'Output file', 'exec_groups': 'Exec groups'})",
        "def _impl(target, ctx):",
        "  output_jar = ctx.actions.declare_file(ctx.label.name + '_dummy_output_aspect.jar')",
        "  " + action + "(",
        actionParameters,
        "    outputs = [output_jar],",
        action.equals("ctx.actions.run")
            ? "    executable = '//toolchain:foo_toolchain',"
            : "    command = 'echo',",
        "  )",
        "  exec_groups = ctx.exec_groups",
        "  return [OutputFile(file = output_jar, exec_groups = exec_groups)]",
        "custom_aspect = aspect(",
        "  implementation = _impl,",
        "  attrs = {",
        "     ",
        extraAttributes,
        "  },",
        "  attr_aspects = ['deps'],",
        "  exec_groups = {",
        execGroups,
        "  },",
        "  toolchains = " + toolchains + ",",
        ")");
  }

  /**
   * Creates empty rule and custom aspect on rule's dependencies. Custom aspect produces action with
   * {@code actionParameters}, adds {@code extraAttributes}, defines {@code toolchains}, and adds
   * custom exec groups from {@code execGroups}. Depending on {@code action} parameter, {@code
   * actions.run} or {@code actions.run_shell} is created. This function is used only for testing
   * the aspect, not the rule.
   */
  private void createCustomAspectAndEmptyRule(
      String action,
      String actionParameters,
      String extraAttributes,
      String toolchains,
      String execGroups)
      throws Exception {
    scratch.file(
        "test/aspect.bzl",
        "OutputFile = provider(fields = {'file': 'Output file', 'exec_groups': 'Exec groups'})",
        "def _impl(target, ctx):",
        "  output_jar = ctx.actions.declare_file(ctx.label.name + '_dummy_output_aspect.jar')",
        "  " + action + "(",
        actionParameters,
        "    outputs = [output_jar],",
        action.equals("ctx.actions.run")
            ? "    executable = '//toolchain:foo_toolchain',"
            : "    command = 'echo',",
        "  )",
        "  exec_groups = ctx.exec_groups",
        "  return [OutputFile(file = output_jar, exec_groups = exec_groups)]",
        "custom_aspect = aspect(",
        "  implementation = _impl,",
        "  attrs = {",
        "     ",
        extraAttributes,
        "  },",
        "  attr_aspects = ['deps'],",
        "  exec_groups = {",
        execGroups,
        "  },",
        "  toolchains = " + toolchains + ",",
        ")");
    scratch.file(
        "test/defs.bzl",
        "load('//test:aspect.bzl', 'custom_aspect')",
        "def _impl(ctx):",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'deps': attr.label_list(aspects = [custom_aspect]),",
        "  },",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_dep')",
        "custom_rule(name = 'custom_rule_name', deps= ['custom_rule_dep'])");
  }

  private StarlarkExecGroupCollection getExecGroupsFromAspectProvider(
      ConfiguredAspect configuredAspect) throws Exception {
    StarlarkProvider.Key key =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "OutputFile");
    StarlarkInfo keyInfo = (StarlarkInfo) configuredAspect.get(key);
    return (StarlarkExecGroupCollection) keyInfo.getValue("exec_groups");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_disabledAndAttributeFalse_disabled(String action)
      throws Exception {
    createCustomAspectAndEmptyRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "'_use_auto_exec_groups': attr.bool(default = False),",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "");

    getConfiguredTarget("//test:custom_rule_name");
    ConfiguredAspect configuredAspect = getAspect("//test:aspect.bzl%custom_aspect");
    StarlarkExecGroupCollection aspectExecGroups =
        getExecGroupsFromAspectProvider(configuredAspect);

    assertThat(aspectExecGroups.getToolchainCollectionForTesting().keySet())
        .containsExactly("default-exec-group");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_disabledAndAttributeTrue_enabled(String action)
      throws Exception {
    createCustomAspectAndEmptyRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "'_use_auto_exec_groups': attr.bool(default = True),",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "");

    getConfiguredTarget("//test:custom_rule_name");
    ConfiguredAspect configuredAspect = getAspect("//test:aspect.bzl%custom_aspect");
    StarlarkExecGroupCollection aspectExecGroups =
        getExecGroupsFromAspectProvider(configuredAspect);

    assertThat(aspectExecGroups.getToolchainCollectionForTesting().keySet())
        .containsExactly("default-exec-group", "//rule:toolchain_type_1");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_disabledAndAttributeNotSet_disabled(String action)
      throws Exception {
    createCustomAspectAndEmptyRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "");
    useConfiguration("--incompatible_auto_exec_groups=False");

    getConfiguredTarget("//test:custom_rule_name");
    ConfiguredAspect configuredAspect = getAspect("//test:aspect.bzl%custom_aspect");
    StarlarkExecGroupCollection aspectExecGroups =
        getExecGroupsFromAspectProvider(configuredAspect);

    assertThat(aspectExecGroups.getToolchainCollectionForTesting().keySet())
        .containsExactly("default-exec-group");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_enabledAndAttributeFalse_disabled(String action)
      throws Exception {
    createCustomAspectAndEmptyRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "'_use_auto_exec_groups': attr.bool(default = False),",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    getConfiguredTarget("//test:custom_rule_name");
    ConfiguredAspect configuredAspect = getAspect("//test:aspect.bzl%custom_aspect");
    StarlarkExecGroupCollection aspectExecGroups =
        getExecGroupsFromAspectProvider(configuredAspect);

    assertThat(aspectExecGroups.getToolchainCollectionForTesting().keySet())
        .containsExactly("default-exec-group");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_enabledAndAttributeTrue_enabled(String action)
      throws Exception {
    createCustomAspectAndEmptyRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "'_use_auto_exec_groups': attr.bool(default = True),",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    getConfiguredTarget("//test:custom_rule_name");
    ConfiguredAspect configuredAspect = getAspect("//test:aspect.bzl%custom_aspect");
    StarlarkExecGroupCollection aspectExecGroups =
        getExecGroupsFromAspectProvider(configuredAspect);

    assertThat(aspectExecGroups.getToolchainCollectionForTesting().keySet())
        .containsExactly("default-exec-group", "//rule:toolchain_type_1");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_enabledAndAttributeNotSet_enabled(String action)
      throws Exception {
    createCustomAspectAndEmptyRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    getConfiguredTarget("//test:custom_rule_name");
    ConfiguredAspect configuredAspect = getAspect("//test:aspect.bzl%custom_aspect");
    StarlarkExecGroupCollection aspectExecGroups =
        getExecGroupsFromAspectProvider(configuredAspect);

    assertThat(aspectExecGroups.getToolchainCollectionForTesting().keySet())
        .containsExactly("default-exec-group", "//rule:toolchain_type_1");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void execGroups_customAspectOnCustomRule(String action) throws Exception {
    String customExecGroups =
        "    'aspect_custom_exec_group': exec_group(\n"
            + "      exec_compatible_with = ['//platforms:constraint_1'],\n"
            + "      toolchains = ['//rule:toolchain_type_1'],\n"
            + "    ),\n";
    createCustomAspect(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_2',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_2']",
        /* execGroups= */ customExecGroups);
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ConfiguredTarget targetDep = (ConfiguredTarget) getRuleContext(target).getPrerequisite("deps");
    ConfiguredAspect configuredAspect = getAspect("//test:aspect.bzl%custom_aspect");
    StarlarkExecGroupCollection aspectExecGroups =
        getExecGroupsFromAspectProvider(configuredAspect);

    assertThat(getRuleContext(target).getExecGroups().execGroups().keySet())
        .containsExactly("//rule:toolchain_type_1");
    assertThat(getRuleContext(targetDep).getExecGroups().execGroups().keySet())
        .containsExactly("//rule:toolchain_type_1");
    assertThat(aspectExecGroups.getToolchainCollectionForTesting().keySet())
        .containsExactly(
            "//rule:toolchain_type_2", "default-exec-group", "aspect_custom_exec_group");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void execPlatforms_customAspectOnCustomRule(String action) throws Exception {
    String customExecGroups =
        "    'aspect_custom_exec_group': exec_group(\n"
            + "      exec_compatible_with = ['//platforms:constraint_1'],\n"
            + "      toolchains = ['//rule:toolchain_type_1'],\n"
            + "    ),\n";
    createCustomAspect(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_2',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_2']",
        /* execGroups= */ customExecGroups);
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ConfiguredTarget targetDep = (ConfiguredTarget) getRuleContext(target).getPrerequisite("deps");
    ConfiguredAspect configuredAspect = getAspect("//test:aspect.bzl%custom_aspect");
    Action targetAction = getGeneratingAction(target, "test/custom_rule_name_dummy_output.jar");
    Action targetDepAction =
        getGeneratingAction(targetDep, "test/custom_rule_dep_dummy_output.jar");
    Action aspectAction = (Action) configuredAspect.getActions().get(0);

    assertThat(targetAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
    assertThat(targetDepAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
    assertThat(aspectAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_2"));
  }
}
