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

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

import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.testutil.Scratch;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Test of common logic between Starlark-defined transitions. Rule-transition- or
 * attr-transition-specific logic should be tested in {@link StarlarkRuleTransitionProviderTest} and
 * {@link StarlarkAttrTransitionProviderTest}.
 */
@RunWith(JUnit4.class)
public class StarlarkTransitionTest extends BuildViewTestCase {
  static void writeAllowlistFile(Scratch scratch) throws Exception {
    scratch.file(
        "tools/allowlists/function_transition_allowlist/BUILD",
        "package_group(",
        "    name = 'function_transition_allowlist',",
        "    packages = [",
        "        '//test/...',",
        "    ],",
        ")");
  }

  @Test
  public void testDupeSettingsInInputsThrowsError() throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _setting_impl(ctx):",
        "  return []",
        "string_flag = rule(",
        "  implementation = _setting_impl,",
        "  build_setting = config.string(flag=True),",
        ")",
        "def _transition_impl(settings, attr):",
        "  return {'//test:formation': 'mesa'}",
        "formation_transition = transition(",
        "  implementation = _transition_impl,",
        "  inputs = ['@//test:formation', '//test:formation'],", // duplicates here
        "  outputs = ['//test:formation'],",
        ")",
        "def _impl(ctx):",
        "  return []",
        "state = rule(",
        "  implementation = _impl,",
        "  cfg = formation_transition,",
        "  attrs = {",
        "    '_allowlist_function_transition': attr.label(",
        "        default = '//tools/allowlists/function_transition_allowlist',",
        "    ),",
        "  })");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'state', 'string_flag')",
        "state(name = 'arizona')",
        "string_flag(name = 'formation', build_setting_default = 'canyon')");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:arizona");
    assertContainsEvent(
        "Transition declares duplicate build setting '@//test:formation' in INPUTS");
  }

  @Test
  public void testDupeSettingsInOutputsThrowsError() throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _setting_impl(ctx):",
        "  return []",
        "string_flag = rule(",
        "  implementation = _setting_impl,",
        "  build_setting = config.string(flag=True),",
        ")",
        "def _transition_impl(settings, attr):",
        "  return {'//test:formation': 'mesa'}",
        "formation_transition = transition(",
        "  implementation = _transition_impl,",
        "  inputs = ['//test:formation'],",
        "  outputs = ['@//test:formation', '//test:formation'],", // duplicates here
        ")",
        "def _impl(ctx):",
        "  return []",
        "state = rule(",
        "  implementation = _impl,",
        "  cfg = formation_transition,",
        "  attrs = {",
        "    '_allowlist_function_transition': attr.label(",
        "        default = '//tools/allowlists/function_transition_allowlist',",
        "    ),",
        "  })");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'state', 'string_flag')",
        "state(name = 'arizona')",
        "string_flag(name = 'formation', build_setting_default = 'canyon')");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:arizona");
    assertContainsEvent(
        "Transition declares duplicate build setting '@//test:formation' in OUTPUTS");
  }

  @Test
  public void testDifferentFormsOfFlagInInputsAndOutputs() throws Exception {
    writeAllowlistFile(scratch);
    scratch.file(
        "test/defs.bzl",
        "def _setting_impl(ctx):",
        "  return []",
        "string_flag = rule(",
        "  implementation = _setting_impl,",
        "  build_setting = config.string(flag=True),",
        ")",
        "def _transition_impl(settings, attr):",
        "  return {",
        "    '//test:formation': settings['@//test:formation']+'-transitioned',",
        "  }",
        "formation_transition = transition(",
        "  implementation = _transition_impl,",
        "  inputs = ['@//test:formation'],",
        "  outputs = ['//test:formation'],",
        ")",
        "def _impl(ctx):",
        "  return []",
        "state = rule(",
        "  implementation = _impl,",
        "  cfg = formation_transition,",
        "  attrs = {",
        "    '_allowlist_function_transition': attr.label(",
        "        default = '//tools/allowlists/function_transition_allowlist',",
        "    ),",
        "  })");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'state', 'string_flag')",
        "state(name = 'arizona')",
        "string_flag(name = 'formation', build_setting_default = 'canyon')");

    Map<Label, Object> starlarkOptions =
        getConfiguration(getConfiguredTarget("//test:arizona")).getOptions().getStarlarkOptions();
    assertThat(starlarkOptions).hasSize(1);
    assertThat(starlarkOptions.get(Label.parseAbsoluteUnchecked("//test:formation")))
        .isEqualTo("canyon-transitioned");
  }
}
