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

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

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.testing.EqualsTester;
import com.google.devtools.build.lib.analysis.config.BuildOptions.MapBackedChecksumCache;
import com.google.devtools.build.lib.analysis.config.BuildOptions.OptionsChecksumCache;
import com.google.devtools.build.lib.analysis.util.ConfigurationTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.rules.objc.J2ObjcConfiguration;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.common.options.Options;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link BuildConfigurationValue}. */
@RunWith(JUnit4.class)
public final class BuildConfigurationValueTest extends ConfigurationTestCase {

  @Test
  public void testBasics() throws Exception {
    if (analysisMock.isThisBazel()) {
      return;
    }

    BuildConfigurationValue config = create("--cpu=piii");
    String outputDirPrefix =
        outputBase + "/execroot/" + config.getWorkspaceName() + "/blaze-out/.*piii-fastbuild";

    assertThat(config.getOutputDirectory(RepositoryName.MAIN).getRoot().toString())
        .matches(outputDirPrefix);
    assertThat(config.getBinDirectory(RepositoryName.MAIN).getRoot().toString())
        .matches(outputDirPrefix + "/bin");
    assertThat(config.getTestLogsDirectory(RepositoryName.MAIN).getRoot().toString())
        .matches(outputDirPrefix + "/testlogs");
  }

  @Test
  public void testPlatformSuffix() throws Exception {
    if (analysisMock.isThisBazel()) {
      return;
    }

    BuildConfigurationValue config = create("--platform_suffix=test");
    assertThat(config.getOutputDirectory(RepositoryName.MAIN).getRoot().toString())
        .matches(
            outputBase
                + "/execroot/"
                + config.getWorkspaceName()
                + "/blaze-out/.*k8-fastbuild-test");
  }

  @Test
  public void testEnvironment() throws Exception {
    if (analysisMock.isThisBazel()) {
      return;
    }

    ImmutableMap<String, String> env = create().getLocalShellEnvironment();
    assertThat(env).containsEntry("LANG", "en_US");
    assertThat(env).containsKey("PATH");
    assertThat(env.get("PATH")).contains("/bin:/usr/bin");
  }

  @Test
  public void testCaching() {
    CoreOptions a = Options.getDefaults(CoreOptions.class);
    CoreOptions b = Options.getDefaults(CoreOptions.class);
    // The String representations of the CoreOptions must be equal even if these are
    // different objects, if they were created with the same options (no options in this case).
    assertThat(b.toString()).isEqualTo(a.toString());
    assertThat(b.cacheKey()).isEqualTo(a.cacheKey());
  }

  @Test
  public void testTargetEnvironment() throws Exception {
    BuildConfigurationValue oneEnvConfig = create("--target_environment=//foo");
    assertThat(oneEnvConfig.getTargetEnvironments()).containsExactly(Label.parseCanonical("//foo"));

    BuildConfigurationValue twoEnvsConfig =
        create("--target_environment=//foo", "--target_environment=//bar");
    assertThat(twoEnvsConfig.getTargetEnvironments())
        .containsExactly(Label.parseCanonical("//foo"), Label.parseCanonical("//bar"));

    BuildConfigurationValue noEnvsConfig = create();
    assertThat(noEnvsConfig.getTargetEnvironments()).isEmpty();
  }

  @Test
  public void testGlobalMakeVariableOverride() throws Exception {
    assertThat(create().getMakeEnvironment()).containsEntry("COMPILATION_MODE", "fastbuild");
    BuildConfigurationValue config = create("--define", "COMPILATION_MODE=fluttershy");
    assertThat(config.getMakeEnvironment()).containsEntry("COMPILATION_MODE", "fluttershy");
  }

  @Test
  public void testGetBuildOptionDetails() throws Exception {
    // Directly defined options:
    assertThat(create("-c", "dbg").getBuildOptionDetails().getOptionValue("compilation_mode"))
        .isEqualTo(CompilationMode.DBG);
    assertThat(create("-c", "opt").getBuildOptionDetails().getOptionValue("compilation_mode"))
        .isEqualTo(CompilationMode.OPT);

    // Options defined in a fragment:
    assertThat(create("--force_pic").getBuildOptionDetails().getOptionValue("force_pic"))
        .isEqualTo(Boolean.TRUE);
    assertThat(create("--noforce_pic").getBuildOptionDetails().getOptionValue("force_pic"))
        .isEqualTo(Boolean.FALSE);

    // Legitimately null option:
    assertThat(create().getBuildOptionDetails().getOptionValue("test_filter")).isNull();
  }

  @Test
  public void testConfigFragmentsAreShareableAcrossConfigurations() throws Exception {
    // Note we can't use any fragments that load files (e.g. CROSSTOOL) because those get
    // Skyframe-invalidated between create() calls.
    BuildConfigurationValue config1 = create("--javacopt=foo");
    BuildConfigurationValue config2 = create("--javacopt=bar");
    BuildConfigurationValue config3 = create("--j2objc_translation_flags=baz");
    // Shared because all j2objc options are the same:
    assertThat(config1.getFragment(J2ObjcConfiguration.class))
        .isSameInstanceAs(config2.getFragment(J2ObjcConfiguration.class));
    // Distinct because the j2objc options differ:
    assertThat(config1.getFragment(J2ObjcConfiguration.class))
        .isNotSameInstanceAs(config3.getFragment(J2ObjcConfiguration.class));
  }

  @Test
  public void testCommandLineVariables() throws Exception {
    BuildConfigurationValue config =
        create("--define", "a=b/c:d", "--define", "b=FOO", "--define", "DEFUN=Nope");
    assertThat(config.getCommandLineBuildVariables().get("a")).isEqualTo("b/c:d");
    assertThat(config.getCommandLineBuildVariables().get("b")).isEqualTo("FOO");
    assertThat(config.getCommandLineBuildVariables().get("DEFUN")).isEqualTo("Nope");
  }

  // Regression test for bug #2518997:
  // "--define in blazerc overrides --define from command line"
  @Test
  public void testCommandLineVariablesOverride() throws Exception {
    BuildConfigurationValue config = create("--define", "a=b", "--define", "a=c");
    assertThat(config.getCommandLineBuildVariables().get("a")).isEqualTo("c");
  }

  @Test
  public void testNormalization_definesWithDifferentNames() throws Exception {
    BuildConfigurationValue config = create("--define", "a=1", "--define", "b=2");
    CoreOptions options = config.getOptions().get(CoreOptions.class);
    assertThat(ImmutableMap.copyOf(options.commandLineBuildVariables))
        .containsExactly("a", "1", "b", "2");
  }

  @Test
  public void testNormalization_definesWithSameName() throws Exception {
    BuildConfigurationValue config = create("--define", "a=1", "--define", "a=2");
    CoreOptions options = config.getOptions().get(CoreOptions.class);
    assertThat(ImmutableMap.copyOf(options.commandLineBuildVariables)).containsExactly("a", "2");
    assertThat(config).isEqualTo(create("--define", "a=2"));
  }

  // This is really a test of option parsing, not command-line variable
  // semantics.
  @Test
  public void testCommandLineVariablesWithFunnyCharacters() throws Exception {
    BuildConfigurationValue config =
        create(
            "--define", "foo=#foo",
            "--define", "comma=a,b",
            "--define", "space=foo bar",
            "--define", "thing=a \"quoted\" thing",
            "--define", "qspace=a\\ quoted\\ space",
            "--define", "#a=pounda");
    assertThat(config.getCommandLineBuildVariables().get("foo")).isEqualTo("#foo");
    assertThat(config.getCommandLineBuildVariables().get("comma")).isEqualTo("a,b");
    assertThat(config.getCommandLineBuildVariables().get("space")).isEqualTo("foo bar");
    assertThat(config.getCommandLineBuildVariables().get("thing")).isEqualTo("a \"quoted\" thing");
    assertThat(config.getCommandLineBuildVariables().get("qspace")).isEqualTo("a\\ quoted\\ space");
    assertThat(config.getCommandLineBuildVariables().get("#a")).isEqualTo("pounda");
  }

  @Test
  public void testExecDefine_isAllowedByDefault() throws Exception {
    BuildConfigurationValue cfg = createExec("--define=foo=bar");
    assertThat(cfg.getCommandLineBuildVariables().get("foo")).isEqualTo("bar");
  }

  @Test
  public void testExecDefine_isIgnoredIfExcludedAndNotAllowed() throws Exception {
    BuildConfigurationValue cfg =
        createExec("--define=foo=bar", "--experimental_exclude_defines_from_exec_config=true");
    assertThat(cfg.getCommandLineBuildVariables()).doesNotContainKey("foo");
  }

  @Test
  public void testExecDefine_isPropagatedIfAllowedByFlag() throws Exception {
    BuildConfigurationValue cfg =
        createExec(
            "--define=foo=bar",
            "--experimental_exclude_defines_from_exec_config=true",
            "--experimental_propagate_custom_flag=foo",
            "--define=baz=qux");
    assertThat(cfg.getCommandLineBuildVariables()).containsEntry("foo", "bar");
    assertThat(cfg.getCommandLineBuildVariables()).doesNotContainEntry("baz", "qux");
  }

  @Test
  public void testExecStarlarkFlag_isAllowedByDefault() throws Exception {
    scratch.file(
        "my_starlark_flag/rule_defs.bzl",
        """
        def _impl(ctx):
            return []

        bool_flag = rule(
            implementation = _basic_impl,
            build_setting = config.bool(flag = True),
        )
        """);
    scratch.file(
        "my_starlark_flag/BUILD",
        """
        load("//:my_starlark_flag:rule_defs.bzl", "bool_flag")

        bool_flag(
            name = "starlark_flag",
            build_setting_default = "False",
        )
        """);
    BuildConfigurationValue cfg =
        createExec(ImmutableMap.of("//my_starlark_flag:starlark_flag", "true"));
    assertThat(
            cfg.getOptions()
                .getStarlarkOptions()
                .get(Label.parseCanonicalUnchecked("//my_starlark_flag:starlark_flag")))
        .isEqualTo("true");
  }

  @Test
  public void testExecStarlarkFlag_isIgnoredIfExcludedAndNotAllowed() throws Exception {
    scratch.file(
        "my_starlark_flag/rule_defs.bzl",
        """
        def _impl(ctx):
            return []

        bool_flag = rule(
            implementation = _basic_impl,
            build_setting = config.bool(flag = True),
        )
        """);
    scratch.file(
        "my_starlark_flag/BUILD",
        """
        load("//my_starlark_flag:rule_defs.bzl", "bool_flag")

        bool_flag(
            name = "starlark_flag",
            build_setting_default = "False",
        )
        """);
    BuildConfigurationValue cfg =
        createExec(
            ImmutableMap.of("//my_starlark_flag:starlark_flag", "true"),
            "--experimental_exclude_starlark_flags_from_exec_config=true");
    assertThat(
            cfg.getOptions()
                .getStarlarkOptions()
                .get(Label.parseCanonicalUnchecked("//my_starlark_flag:starlark_flag")))
        .isNull();
  }

  @Test
  public void testExecStarlarkFlag_isPropagatedIfAllowedByFlag() throws Exception {
    scratch.file(
        "my_starlark_flag/rule_defs.bzl",
        """
        def _impl(ctx):
            return []

        bool_flag = rule(
            implementation = _basic_impl,
            build_setting = config.bool(flag = True),
        )
        """);
    scratch.file(
        "my_starlark_flag/BUILD",
        """
        load("//my_starlark_flag:rule_defs.bzl", "bool_flag")

        bool_flag(
            name = "starlark_flag",
            build_setting_default = "False",
        )

        bool_flag(
            name = "other_starlark_flag",
            build_setting_default = "False",
        )
        """);
    BuildConfigurationValue cfg =
        createExec(
            ImmutableMap.of(
                "//my_starlark_flag:starlark_flag",
                "true",
                "//my_starlark_flag:other_starlark_flag",
                "true"),
            "--experimental_exclude_starlark_flags_from_exec_config=true",
            "--experimental_propagate_custom_flag=//my_starlark_flag:starlark_flag");
    assertThat(
            cfg.getOptions()
                .getStarlarkOptions()
                .get(Label.parseCanonicalUnchecked("//my_starlark_flag:starlark_flag")))
        .isEqualTo("true");
    assertThat(
            cfg.getOptions()
                .getStarlarkOptions()
                .get(Label.parseCanonicalUnchecked("//my_starlark_flag:other_starlark_flag")))
        .isNull();
  }

  @Test
  public void testHostCompilationModeDefault() throws Exception {
    BuildConfigurationValue cfg = createExec();
    assertThat(cfg.getCompilationMode()).isEqualTo(CompilationMode.OPT);
  }

  @Test
  public void testHostCompilationModeNonDefault() throws Exception {
    BuildConfigurationValue cfg = createExec("--host_compilation_mode=dbg");
    assertThat(cfg.getCompilationMode()).isEqualTo(CompilationMode.DBG);
  }

  @Test
  public void testIncompatibleMergeGenfilesDirectory() throws Exception {
    BuildConfigurationValue target = create("--incompatible_merge_genfiles_directory");
    BuildConfigurationValue exec = createExec("--incompatible_merge_genfiles_directory");
    assertThat(target.getGenfilesDirectory(RepositoryName.MAIN))
        .isEqualTo(target.getBinDirectory(RepositoryName.MAIN));
    assertThat(exec.getGenfilesDirectory(RepositoryName.MAIN))
        .isEqualTo(exec.getBinDirectory(RepositoryName.MAIN));
  }

  private ImmutableList<BuildConfigurationValue> getTestConfigurations() throws Exception {
    return ImmutableList.of(
        create(),
        create("--cpu=piii"),
        create("--javacopt=foo"),
        create("--platform_suffix=-test"),
        create("--target_environment=//foo", "--target_environment=//bar"),
        create("--incompatible_merge_genfiles_directory"),
        create(
            "--define",
            "foo=#foo",
            "--define",
            "comma=a,b",
            "--define",
            "space=foo bar",
            "--define",
            "thing=a \"quoted\" thing",
            "--define",
            "qspace=a\\ quoted\\ space",
            "--define",
            "#a=pounda"));
  }

  @Test
  public void testCodec() throws Exception {
    // Unnecessary ImmutableList.copyOf apparently necessary to choose non-varargs constructor.
    new SerializationTester(ImmutableList.copyOf(getTestConfigurations()))
        .addDependency(FileSystem.class, getScratch().getFileSystem())
        .addDependency(OptionsChecksumCache.class, new MapBackedChecksumCache())
        .setVerificationFunction(BuildConfigurationValueTest::verifyDeserialized)
        .runTests();
  }

  @Test
  public void testKeyCodec() throws Exception {
    new SerializationTester(
            getTestConfigurations().stream()
                .map(BuildConfigurationValue::getKey)
                .collect(ImmutableList.toImmutableList()))
        .addDependency(OptionsChecksumCache.class, new MapBackedChecksumCache())
        .runTests();
  }

  @Test
  public void testPlatformInOutputDir_legacy_defaultPlatform() throws Exception {
    BuildConfigurationValue config =
        create(
            "--experimental_platform_in_output_dir",
            "--experimental_use_platforms_in_output_dir_legacy_heuristic",
            "--cpu=k8");

    assertThat(config.getOutputDirectory(RepositoryName.MAIN).getRoot().toString())
        .matches(".*/[^/]+-out/k8-fastbuild");
  }

  @Test
  public void testPlatformInOutputDir_legacy_withPlatform() throws Exception {
    scratch.file("platform/BUILD", "platform(name = 'alpha')");
    BuildConfigurationValue config =
        create(
            "--experimental_platform_in_output_dir",
            "--experimental_use_platforms_in_output_dir_legacy_heuristic",
            "--platforms=//platform:alpha");

    assertThat(config.getOutputDirectory(RepositoryName.MAIN).getRoot().toString())
        .matches(".*/[^/]+-out/alpha-fastbuild");
  }

  @Test
  public void testPlatformInOutputDir_defaultPlatform() throws Exception {
    BuildConfigurationValue config =
        create(
            "--experimental_platform_in_output_dir",
            "--noexperimental_use_platforms_in_output_dir_legacy_heuristic",
            "--cpu=k8");
    // See tests of these flags with platform_mappings for more realistic results.
    assertThat(config.getOutputDirectory(RepositoryName.MAIN).getRoot().toString())
        .matches(".*/[^/]+-out/platform-\\w*-fastbuild");
  }

  @Test
  public void testPlatformInOutputDir_withPlatform() throws Exception {
    scratch.file("platform/BUILD", "platform(name = 'alpha')");
    BuildConfigurationValue config =
        create(
            "--experimental_platform_in_output_dir",
            "--noexperimental_use_platforms_in_output_dir_legacy_heuristic",
            "--platforms=//platform:alpha");

    assertThat(config.getOutputDirectory(RepositoryName.MAIN).getRoot().toString())
        .matches(".*/[^/]+-out/platform-\\w*-fastbuild");
  }

  @Test
  public void testPlatformInOutputDir_withPlatformAndMatchingOverride() throws Exception {
    scratch.file("platform/BUILD", "platform(name = 'alpha')");
    BuildConfigurationValue config =
        create(
            "--experimental_platform_in_output_dir",
            "--noexperimental_use_platforms_in_output_dir_legacy_heuristic",
            "--experimental_override_name_platform_in_output_dir=//platform:alpha=alpha",
            "--platforms=//platform:alpha");

    assertThat(config.getOutputDirectory(RepositoryName.MAIN).getRoot().toString())
        .matches(".*/[^/]+-out/alpha-fastbuild");
  }

  @Test
  public void testPlatformInOutputDir_withPlatformAndNonMatchingOverride() throws Exception {
    scratch.file("platform/BUILD", "platform(name = 'alpha')");
    BuildConfigurationValue config =
        create(
            "--experimental_platform_in_output_dir",
            "--noexperimental_use_platforms_in_output_dir_legacy_heuristic",
            "--experimental_override_name_platform_in_output_dir=//platform:beta=beta",
            "--platforms=//platform:alpha");

    assertThat(config.getOutputDirectory(RepositoryName.MAIN).getRoot().toString())
        .matches(".*/[^/]+-out/platform-\\w*-fastbuild");
  }

  @Test
  public void testConfigurationEquality() throws Exception {
    // Note that, in practice, test_arg should not be used as a no-op argument; however,
    // these configurations are never trimmed nor even used to build targets so not an issue.
    new EqualsTester()
        .addEqualityGroup(
            createRaw(parseBuildOptions("--test_arg=1a"), "k8", "testrepo", false),
            createRaw(parseBuildOptions("--test_arg=1a"), "k8", "testrepo", false))
        // Different BuildOptions means non-equal
        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=1b"), "k8", "testrepo", false))
        // Different --experimental_sibling_repository_layout means non-equal
        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=2"), "k8", "testrepo", true))
        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=2"), "k8", "testrepo", false))
        // Different repositoryName means non-equal
        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "k8", "testrepo1", false))
        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "k8", "testrepo2", false))
        // Different transitionDirectoryNameFragment means non-equal
        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "k8", "testrepo", false))
        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "arm", "testrepo", false))
        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "risc", "testrepo", false))
        .testEquals();
  }

  /**
   * Partial verification of deserialized BuildConfigurationValue.
   *
   * <p>Direct comparison of deserialized to subject doesn't work because Fragment classes do not
   * implement equals. This runs the part of BuildConfigurationValue.equals that has equals
   * definitions.
   */
  private static void verifyDeserialized(
      BuildConfigurationValue subject, BuildConfigurationValue deserialized) {
    assertThat(deserialized.getOptions()).isEqualTo(subject.getOptions());
  }
}
