// Copyright 2017 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.apple;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.eventbus.Subscribe;
import com.google.devtools.build.lib.actions.ExecutionRequirements;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.XcodeConfigEvent;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.ConfiguredAttributeMapper;
import com.google.devtools.build.lib.packages.Provider;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.xcode.proto.XcodeConfig.XcodeConfigRuleInfo;
import com.google.devtools.build.lib.xcode.proto.XcodeConfig.XcodeConfigRuleInfo.Availability;
import com.google.devtools.build.lib.xcode.proto.XcodeConfig.XcodeVersionInfo;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for the {@code xcode_config} rule. */
@RunWith(JUnit4.class)
public class XcodeConfigTest extends BuildViewTestCase {
  private static class EventRecorder {
    public XcodeConfigEvent xcodeConfigEvent;

    @Subscribe
    public synchronized void setXcodeConfigInfo(XcodeConfigEvent xcodeConfigEvent) {
      // We only care about the top level xcode_config, so drop earlier events.
      this.xcodeConfigEvent = xcodeConfigEvent;
    }
  }

  private final EventRecorder eventRecorder = new EventRecorder();

  @Before
  public void setUp() {
    eventBus.register(eventRecorder);
  }

  @Test
  public void testEmptyConfig_noVersionFlag() throws Exception {
    scratch.file("xcode/BUILD", "xcode_config(name = 'foo',)");
    useConfiguration("--xcode_version_config=//xcode:foo");

    assertIosSdkVersion(AppleCommandLineOptions.DEFAULT_IOS_SDK_VERSION);
  }

  @Test
  public void testDefaultVersion() throws Exception {
    BuildFileBuilder fileBuilder = new BuildFileBuilder();
    fileBuilder
        .addExplicitVersion("version512", "5.1.2", true)
        .addExplicitVersion("version84", "8.4", false)
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version_config=//xcode:foo");

    assertXcodeVersion("5.1.2");
    assertAvailability(XcodeConfigInfo.Availability.UNKNOWN);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));
  }

  @Test
  public void testMutualAndExplicitXcodesThrows() throws Exception {
    scratch.file(
        "xcode/BUILD",
        "xcode_config(",
        "    name = 'foo',",
        "    versions = [':version512', ':version84'],",
        "    default = ':version512',",
        "    remote_versions = ':remote',",
        "    local_versions = ':local',",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        ")",
        "xcode_version(",
        "    name = 'version84',",
        "    version = '8.4',",
        ")",
        "available_xcodes(",
        "    name = 'remote',",
        "    versions = [':version512',],",
        "    default = ':version512',",
        ")",
        "available_xcodes(",
        "    name = 'local',",
        "    versions = [':version84',],",
        "    default = ':version84',",
        ")");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent("'versions' may not be set if '[local,remote]_versions' is set");
  }

  @Test
  public void testMutualAndDefaultThrows() throws Exception {
    scratch.file(
        "xcode/BUILD",
        "xcode_config(",
        "    name = 'foo',",
        "    default = ':version512',",
        "    remote_versions = ':remote',",
        "    local_versions = ':local',",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        ")",
        "xcode_version(",
        "    name = 'version84',",
        "    version = '8.4',",
        ")",
        "available_xcodes(",
        "    name = 'remote',",
        "    versions = [':version512',],",
        "    default = ':version512',",
        ")",
        "available_xcodes(",
        "    name = 'local',",
        "    versions = [':version84',],",
        "    default = ':version84',",
        ")");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent("'default' may not be set if '[local,remote]_versions' is set.");
  }

  @Test
  public void testNoLocalXcodesThrows() throws Exception {
    scratch.file(
        "xcode/BUILD",
        "xcode_config(",
        "    name = 'foo',",
        "    remote_versions = ':remote',",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        ")",
        "available_xcodes(",
        "    name = 'remote',",
        "    versions = [':version512',],",
        "    default = ':version512',",
        ")");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent("if 'remote_versions' are set, you must also set 'local_versions'");
  }

  @Test
  public void testAcceptFlagForMutuallyAvailable() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version512", "5.1.2", true)
        .addRemoteVersion("version84", "8.4", false)
        .addLocalVersion("version84", "8.4", true)
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version=8.4", "--xcode_version_config=//xcode:foo");
    assertXcodeVersion("8.4");
    assertAvailability(XcodeConfigInfo.Availability.BOTH);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));

    assertNoEvents();
  }

  @Test
  public void testPreferFlagOverMutuallyAvailable() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version512", "5.1.2", true)
        .addRemoteVersion("version84", "8.4", false)
        .addLocalVersion("version84", "8.4", true)
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version=5.1.2", "--xcode_version_config=//xcode:foo");
    assertXcodeVersion("5.1.2");
    assertAvailability(XcodeConfigInfo.Availability.REMOTE);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN,
            ExecutionRequirements.NO_LOCAL,
            ExecutionRequirements.REQUIREMENTS_SET));

    assertContainsEvent(
        "--xcode_version=5.1.2 specified, but it is not available locally. Your build"
            + " will fail if any actions require a local Xcode.");
  }

  @Test
  public void testPreferMutual_choosesLocalDefaultOverNewest() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version512", "5.1.2", true)
        .addRemoteVersion("version84", "8.4", false)
        .addLocalVersion("version512", "5.1.2", true)
        .addLocalVersion("version84", "8.4", false)
        .write(scratch, "xcode/BUILD");

    useConfiguration(
        "--experimental_prefer_mutual_xcode=true", "--xcode_version_config=//xcode:foo");
    assertXcodeVersion("5.1.2");
    assertAvailability(XcodeConfigInfo.Availability.BOTH);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));
  }

  @Test
  public void testWarnWithExplicitLocalOnlyVersion() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version512", "5.1.2", true)
        .addLocalVersion("version84", "8.4", true)
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version=8.4", "--xcode_version_config=//xcode:foo");
    assertXcodeVersion("8.4");
    assertAvailability(XcodeConfigInfo.Availability.LOCAL);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN,
            ExecutionRequirements.NO_REMOTE,
            ExecutionRequirements.REQUIREMENTS_SET));

    assertContainsEvent(
        "--xcode_version=8.4 specified, but it is not available remotely. Actions"
            + " requiring Xcode will be run locally, which could make your build"
            + " slower.");
  }

  @Test
  public void testPreferLocalDefaultIfNoMutualNoFlagDifferentMainVersion() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version512", "5.1.2", true)
        .addLocalVersion("version84", "8.4", true)
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version_config=//xcode:foo");
    assertXcodeVersion("8.4");
    assertAvailability(XcodeConfigInfo.Availability.LOCAL);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN,
            ExecutionRequirements.NO_REMOTE,
            ExecutionRequirements.REQUIREMENTS_SET));

    assertContainsEvent(
        "Using a local Xcode version, '8.4', since there are no"
            + " remotely available Xcodes on this machine. Consider downloading one of the"
            + " remotely available Xcode versions (5.1.2)");
  }

  @Test
  public void testPreferLocalDefaultIfNoMutualNoFlagDifferentBuildAlias() throws Exception {
    // Version 10.0 of different builds are not matched
    new BuildFileBuilder()
        .addRemoteVersion("version10", "10.0", true, "10.0.0.101ff", "10.0")
        .addLocalVersion("version10.0.0.10C504", "10.0.0.10C504", true, "10.0.0.10C504", "10.0")
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version_config=//xcode:foo");
    assertXcodeVersion("10.0.0.10C504");
    assertAvailability(XcodeConfigInfo.Availability.LOCAL);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN,
            ExecutionRequirements.NO_REMOTE,
            ExecutionRequirements.REQUIREMENTS_SET));

    assertContainsEvent(
        "Using a local Xcode version, '10.0.0.10C504', since there are no"
            + " remotely available Xcodes on this machine. Consider downloading one of the"
            + " remotely available Xcode versions (10.0)");
  }

  @Test
  public void testPreferLocalDefaultIfNoMutualNoFlagDifferentFullVersion() throws Exception {
    // Version 10.0 of different builds are not matched
    new BuildFileBuilder()
        .addRemoteVersion("version10", "10.0.0.101ff", true, "10.0", "10.0.0.101ff")
        .addLocalVersion("version10.0.0.10C504", "10.0.0.10C504", true, "10.0.0.10C504", "10.0")
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version_config=//xcode:foo");
    assertXcodeVersion("10.0.0.10C504");
    assertAvailability(XcodeConfigInfo.Availability.LOCAL);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN,
            ExecutionRequirements.NO_REMOTE,
            ExecutionRequirements.REQUIREMENTS_SET));

    assertContainsEvent(
        "Using a local Xcode version, '10.0.0.10C504', since there are no"
            + " remotely available Xcodes on this machine. Consider downloading one of the"
            + " remotely available Xcode versions (10.0.0.101ff)");
  }

  @Test
  public void testChooseNewestMutualXcode() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version92", "9.2", true)
        .addRemoteVersion("version10", "10", false, "10.0.0.10C504")
        .addRemoteVersion("version84", "8.4", false)
        .addLocalVersion("version9", "9", true)
        .addLocalVersion("version84", "8.4", false)
        .addLocalVersion("version10.0.0.10C504", "10.0.0.10C504", false, "10.0")
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version_config=//xcode:foo");
    assertXcodeVersion("10");
    assertAvailability(XcodeConfigInfo.Availability.BOTH);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));

    assertNoEvents();
  }

  @Test
  public void testPreferMutualXcodeFalseOverridesMutual() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version10", "10", true, "10.0.0.10C504")
        .addLocalVersion("version84", "8.4", true)
        .addLocalVersion("version10.0.0.10C504", "10.0.0.10C504", false, "10.0")
        .write(scratch, "xcode/BUILD");

    useConfiguration(
        "--xcode_version_config=//xcode:foo", "--experimental_prefer_mutual_xcode=false");
    assertXcodeVersion("8.4");
    assertAvailability(XcodeConfigInfo.Availability.LOCAL);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));

    assertContainsEvent("You passed --experimental_prefer_mutual_xcode=false");
    assertContainsEvent("consider using --experimental_prefer_mutual_xcode=true");
  }

  @Test
  public void testLocalDefaultCanBeMutuallyAvailable() throws Exception {
    // Passing "--experimental_prefer_mutual_xcode=false" allows toggling between Xcode versions
    // using xcode-select. This test ensures that if the version from xcode-select is available
    // remotely, both local and remote execution are enabled.
    new BuildFileBuilder()
        .addRemoteVersion("version10", "10", true, "10.0.0.10C504")
        .addLocalVersion("version10.0.0.10C504", "10.0.0.10C504", true, "10.0")
        .write(scratch, "xcode/BUILD");

    useConfiguration(
        "--xcode_version_config=//xcode:foo", "--experimental_prefer_mutual_xcode=false");
    assertXcodeVersion("10");
    assertAvailability(XcodeConfigInfo.Availability.BOTH);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));

    assertNoEvents();
  }

  @Test
  public void testPreferLocalDefaultOverDifferentBuild() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version10", "10", true, "10.0.0.10C1ff")
        .addLocalVersion("version10.0.0.10C504", "10.0.0.10C504", true, "10")
        .write(scratch, "xcode/BUILD");

    useConfiguration(
        "--xcode_version_config=//xcode:foo", "--experimental_prefer_mutual_xcode=false");
    assertXcodeVersion("10.0.0.10C504");
    assertAvailability(XcodeConfigInfo.Availability.LOCAL);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));

    assertContainsEvent(
        "Using a local Xcode version, '10.0.0.10C504', since there are no"
            + " remotely available Xcodes on this machine. Consider downloading one of the"
            + " remotely available Xcode versions (10)");
  }

  @Test
  public void testInvalidXcodeFromMutualThrows() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version512", "5.1.2", true)
        .addRemoteVersion("version84", "8.4", false)
        .addLocalVersion("version84", "8.4", true)
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version=6");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent(
        "--xcode_version=6 specified, but '6' is not an available Xcode version."
            + " localy available versions: [8.4]. remotely available versions:"
            + " [5.1.2, 8.4].");
  }

  @Test
  public void xcodeVersionConfig_isFunction() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(xcode_version ="
            + " apple_common.XcodeVersionConfig("
            + " iosSdkVersion='1.1',"
            + " iosMinimumOsVersion='1.2',"
            + " watchosSdkVersion='1.3',"
            + " watchosMinimumOsVersion='1.4',"
            + " tvosSdkVersion='1.5',"
            + " tvosMinimumOsVersion='1.6',"
            + " macosSdkVersion='1.7',"
            + " macosMinimumOsVersion='1.8',"
            + " xcodeVersion='1.9'))]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
    scratch.file("foo/BUILD", "load(':extension.bzl', 'my_rule')", "my_rule(name='test')");
    assertNoEvents();
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:test");
    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));
    assertThat(info.getValue("xcode_version"))
        .isEqualTo(
            new XcodeConfigInfo(
                DottedVersion.fromStringUnchecked("1.1"),
                DottedVersion.fromStringUnchecked("1.2"),
                DottedVersion.fromStringUnchecked("1.3"),
                DottedVersion.fromStringUnchecked("1.4"),
                DottedVersion.fromStringUnchecked("1.5"),
                DottedVersion.fromStringUnchecked("1.6"),
                DottedVersion.fromStringUnchecked("1.7"),
                DottedVersion.fromStringUnchecked("1.8"),
                DottedVersion.fromStringUnchecked("1.9"),
                XcodeConfigInfo.Availability.UNKNOWN,
                /* xcodeVersionFlagValue= */ "",
                /* includeXcodeReqs= */ false));
  }

  @Test
  public void xcodeVersionConfig_throwsOnBadInput() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(xcode_version ="
            + " apple_common.XcodeVersionConfig("
            + " iosSdkVersion='not a valid dotted version',"
            + " iosMinimumOsVersion='1.2',"
            + " watchosSdkVersion='1.3',"
            + " watchosMinimumOsVersion='1.4',"
            + " tvosSdkVersion='1.5',"
            + " tvosMinimumOsVersion='1.6',"
            + " macosSdkVersion='1.7',"
            + " macosMinimumOsVersion='1.8',"
            + " xcodeVersion='1.9'))]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
    scratch.file("foo/BUILD", "load(':extension.bzl', 'my_rule')", "my_rule(name='test')");
    assertNoEvents();
    assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:test"));
    assertContainsEvent("Dotted version components must all start with the form");
    assertContainsEvent("got 'not a valid dotted version'");
  }

  @Test
  public void xcodeVersionConfig_exposesExpectedAttributes() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  xcode_version ="
            + " apple_common.XcodeVersionConfig("
            + " iosSdkVersion='1.1',"
            + " iosMinimumOsVersion='1.2',"
            + " watchosSdkVersion='1.3',"
            + " watchosMinimumOsVersion='1.4',"
            + " tvosSdkVersion='1.5',"
            + " tvosMinimumOsVersion='1.6',"
            + " macosSdkVersion='1.7',"
            + " macosMinimumOsVersion='1.8',"
            + " xcodeVersion='1.9')",
        "  return [result(xcode_version=xcode_version.xcode_version(),"
            + "min_os=xcode_version.minimum_os_for_platform_type(ctx.fragments.apple.single_arch_platform.platform_type)),]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() },  fragments = ['apple'])");
    scratch.file("foo/BUILD", "load(':extension.bzl', 'my_rule')", "my_rule(name='test')");
    assertNoEvents();
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:test");
    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));
    assertThat(info.getValue("xcode_version").toString()).isEqualTo("1.9");
    assertThat(info.getValue("min_os").toString()).isEqualTo("1.8");
  }

  @Test
  public void testConfigAlias_configSetting() throws Exception {
    scratch.file("starlark/BUILD");
    scratch.file(
        "starlark/version_retriever.bzl",
        "def _version_retriever_impl(ctx):",
        "  xcode_properties = ctx.attr.dep[apple_common.XcodeProperties]",
        "  version = xcode_properties.xcode_version",
        "  return [config_common.FeatureFlagInfo(value=version)]",
        "",
        "version_retriever = rule(",
        "  implementation = _version_retriever_impl,",
        "  attrs = {'dep': attr.label()},",
        ")");

    scratch.file(
        "xcode/BUILD",
        "load('//starlark:version_retriever.bzl', 'version_retriever')",
        "version_retriever(",
        "    name = 'flag_propagator',",
        "    dep = ':alias',",
        ")",
        "",
        "xcode_config(",
        "    name = 'config',",
        "    default = ':version512',",
        "    versions = [':version512', ':version64', ':version12'],",
        ")",
        "",
        "xcode_config_alias(",
        "    name = 'alias'",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version64',",
        "    version = '6.4',",
        "    aliases = ['6.0', 'six', '6'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version12',",
        "    version = '12',",
        ")",
        "config_setting(name = 'xcode_5_1_2',",
        "    flag_values = {':flag_propagator': '5.1.2'})",
        "config_setting(name = 'xcode_6_4',",
        "    flag_values = {':flag_propagator': '6.4'})",
        "genrule(",
        "    name = 'gen',",
        "    srcs = [],",
        "    outs = ['out'],",
        "    cmd = select({",
        "       ':xcode_5_1_2': '5.1.2',",
        "       ':xcode_6_4': '6.4',",
        "       '//conditions:default': 'none'",
        "    }))");

    useConfiguration("--xcode_version_config=//xcode:config");
    assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("5.1.2");

    useConfiguration("--xcode_version_config=//xcode:config", "--xcode_version=6.4");
    assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("6.4");

    useConfiguration("--xcode_version_config=//xcode:config", "--xcode_version=6");
    assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("6.4");

    useConfiguration("--xcode_version_config=//xcode:config", "--xcode_version=12");
    assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("none");
  }

  @Test
  public void testDefaultVersion_configSetting() throws Exception {
    scratch.file("starlark/BUILD");
    scratch.file(
        "starlark/version_retriever.bzl",
        "def _version_retriever_impl(ctx):",
        "  xcode_properties = ctx.attr.dep[apple_common.XcodeProperties]",
        "  version = xcode_properties.xcode_version",
        "  return [config_common.FeatureFlagInfo(value=version)]",
        "",
        "version_retriever = rule(",
        "  implementation = _version_retriever_impl,",
        "  attrs = {'dep': attr.label()},",
        ")");

    scratch.file(
        "xcode/BUILD",
        "load('//starlark:version_retriever.bzl', 'version_retriever')",
        "version_retriever(",
        "    name = 'flag_propagator',",
        "    dep = ':alias',",
        ")",
        "xcode_config_alias(",
        "    name = 'alias'",
        ")",
        "xcode_config(",
        "    name = 'foo',",
        "    default = ':version512',",
        "    versions = [':version512', ':version64'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version64',",
        "    version = '6.4',",
        "    aliases = ['6.0', 'foo', '6'],",
        ")",
        "config_setting(name = 'xcode_5_1_2',",
        "    flag_values = {':flag_propagator': '5.1.2'})",
        "config_setting(name = 'xcode_6_4',",
        "    flag_values = {':flag_propagator': '6.4'})",
        "genrule(",
        "    name = 'gen',",
        "    srcs = [],",
        "    outs = ['out'],",
        "    cmd = select({",
        "       ':xcode_5_1_2': '5.1.2',",
        "       ':xcode_6_4': '6.4',",
        "       '//conditions:default': 'none'",
        "    }))");

    useConfiguration("--xcode_version_config=//xcode:foo");
    assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("5.1.2");

    useConfiguration("--xcode_version_config=//xcode:foo", "--xcode_version=6.4");
    assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("6.4");
  }

  @Test
  public void testValidVersion() throws Exception {
    new BuildFileBuilder()
        .addExplicitVersion("version512", "5.1.2", true)
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version=5.1.2", "--xcode_version_config=//xcode:foo");

    assertXcodeVersion("5.1.2");
    assertAvailability(XcodeConfigInfo.Availability.UNKNOWN);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));
  }

  @Test
  public void testValidAlias_dottedVersion() throws Exception {
    new BuildFileBuilder()
        .addExplicitVersion("version512", "5.1.2", true, "5")
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version=5", "--xcode_version_config=//xcode:foo");

    assertXcodeVersion("5.1.2");
    assertAvailability(XcodeConfigInfo.Availability.UNKNOWN);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));
  }

  @Test
  public void testValidAlias_nonNumerical() throws Exception {
    new BuildFileBuilder()
        .addExplicitVersion("version512", "5.1.2", true, "valid_version")
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version=valid_version", "--xcode_version_config=//xcode:foo");

    assertXcodeVersion("5.1.2");
    assertAvailability(XcodeConfigInfo.Availability.UNKNOWN);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));
  }

  @Test
  public void testInvalidXcodeSpecified() throws Exception {
    new BuildFileBuilder()
        .addExplicitVersion("version512", "5.1.2", true)
        .addExplicitVersion("version84", "8.4", false)
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version=6");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent(
        "--xcode_version=6 specified, but '6' is not an available Xcode version. "
            + "available versions: [5.1.2, 8.4]. If you believe you have '6' installed");
  }

  @Test
  public void testRequiresDefault() throws Exception {
    scratch.file(
        "xcode/BUILD",
        "xcode_config(",
        "    name = 'foo',",
        "    versions = [':version512'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        ")");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent("default version must be specified");
  }

  @Test
  public void testDuplicateAliases_definedVersion() throws Exception {
    new BuildFileBuilder()
        .addExplicitVersion("version512", "5.1.2", true, "5")
        .addExplicitVersion("version5", "5.0", false, "5")
        .write(scratch, "xcode/BUILD");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent(
        "'5' is registered to multiple labels (//xcode:version512, //xcode:version5)");
  }

  @Test
  public void testDuplicateAliases_withinAvailableXcodes() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version512", "5.1.2", true, "5")
        .addRemoteVersion("version5", "5.0", false, "5")
        .addLocalVersion("version5", "5.0", true, "5")
        .write(scratch, "xcode/BUILD");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent(
        "'5' is registered to multiple labels (//xcode:version512, //xcode:version5)");
  }

  @Test
  public void testVersionAliasedToItself() throws Exception {
    new BuildFileBuilder()
        .addExplicitVersion("version512", "5.1.2", true, "5.1.2")
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version_config=//xcode:foo");

    assertXcodeVersion("5.1.2");
    assertAvailability(XcodeConfigInfo.Availability.UNKNOWN);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));
  }

  @Test
  public void testDuplicateVersionNumbers() throws Exception {
    new BuildFileBuilder()
        .addExplicitVersion("version512", "5.1.2", true)
        .addExplicitVersion("version5", "5.1.2", false, "5")
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version=5");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent(
        "'5.1.2' is registered to multiple labels (//xcode:version512, //xcode:version5)");
  }

  @Test
  public void testVersionConflictsWithAlias() throws Exception {
    new BuildFileBuilder()
        .addExplicitVersion("version512", "5.1.2", true)
        .addExplicitVersion("version5", "5.0", false, "5.1.2")
        .write(scratch, "xcode/BUILD");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent(
        "'5.1.2' is registered to multiple labels (//xcode:version512, //xcode:version5)");
  }

  @Test
  public void testDefaultIosSdkVersion() throws Exception {
    scratch.file(
        "xcode/BUILD",
        "xcode_config(",
        "    name = 'foo',",
        "    default = ':version512',",
        "    versions = [':version512', ':version64'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        "    default_ios_sdk_version = '7.1'",
        ")",
        "",
        "xcode_version(",
        "    name = 'version64',",
        "    version = '6.4',",
        "    aliases = ['6.0', 'foo', '6'],",
        "    default_ios_sdk_version = '43.0'",
        ")");
    useConfiguration("--xcode_version_config=//xcode:foo");

    assertXcodeVersion("5.1.2");
    assertIosSdkVersion("7.1");
    assertAvailability(XcodeConfigInfo.Availability.UNKNOWN);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));
  }

  @Test
  public void testDefaultSdkVersions() throws Exception {
    scratch.file(
        "xcode/BUILD",
        "xcode_config(",
        "    name = 'foo',",
        "    default = ':version512',",
        "    versions = [':version512', ':version64'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        "    default_ios_sdk_version = '101',",
        "    default_watchos_sdk_version = '102',",
        "    default_tvos_sdk_version = '103',",
        "    default_macos_sdk_version = '104',",
        ")",
        "",
        "xcode_version(",
        "    name = 'version64',",
        "    version = '6.4',",
        "    aliases = ['6.0', 'foo', '6'],",
        "    default_ios_sdk_version = '43.0'",
        ")");
    useConfiguration("--xcode_version_config=//xcode:foo");

    assertXcodeVersion("5.1.2");
    assertAvailability(XcodeConfigInfo.Availability.UNKNOWN);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));

    ImmutableMap<ApplePlatform, String> platformToVersion =
        ImmutableMap.<ApplePlatform, String>builder()
            .put(ApplePlatform.IOS_SIMULATOR, "101")
            .put(ApplePlatform.WATCHOS_SIMULATOR, "102")
            .put(ApplePlatform.TVOS_SIMULATOR, "103")
            .put(ApplePlatform.MACOS, "104")
            .build();
    for (ApplePlatform platform : platformToVersion.keySet()) {
      DottedVersion version = DottedVersion.fromString(platformToVersion.get(platform));
      assertThat(getSdkVersionForPlatform(platform)).isEqualTo(version);
      assertThat(getMinimumOsVersionForPlatform(platform)).isEqualTo(version);
    }
  }

  @Test
  public void testDefaultSdkVersions_selectedXcode() throws Exception {
    scratch.file(
        "xcode/BUILD",
        "xcode_config(",
        "    name = 'foo',",
        "    default = ':version512',",
        "    versions = [':version512', ':version64'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        "    default_ios_sdk_version = '7.1'",
        ")",
        "",
        "xcode_version(",
        "    name = 'version64',",
        "    version = '6.4',",
        "    aliases = ['6.0', 'foo', '6'],",
        "    default_ios_sdk_version = '43',",
        "    default_watchos_sdk_version = '44',",
        "    default_tvos_sdk_version = '45',",
        "    default_macos_sdk_version = '46',",
        ")");
    useConfiguration("--xcode_version=6", "--xcode_version_config=//xcode:foo");

    assertXcodeVersion("6.4");
    assertAvailability(XcodeConfigInfo.Availability.UNKNOWN);
    assertHasRequirements(
        ImmutableList.of(
            ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET));

    ImmutableMap<ApplePlatform, String> platformToVersion =
        ImmutableMap.<ApplePlatform, String>builder()
            .put(ApplePlatform.IOS_SIMULATOR, "43")
            .put(ApplePlatform.WATCHOS_SIMULATOR, "44")
            .put(ApplePlatform.TVOS_SIMULATOR, "45")
            .put(ApplePlatform.MACOS, "46")
            .build();
    for (ApplePlatform platform : platformToVersion.keySet()) {
      DottedVersion version = DottedVersion.fromString(platformToVersion.get(platform));
      assertThat(getSdkVersionForPlatform(platform)).isEqualTo(version);
      assertThat(getMinimumOsVersionForPlatform(platform)).isEqualTo(version);
    }
  }

  @Test
  public void testOverrideDefaultSdkVersions() throws Exception {
    scratch.file(
        "xcode/BUILD",
        "xcode_config(",
        "    name = 'foo',",
        "    default = ':version512',",
        "    versions = [':version512', ':version64'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        "    default_ios_sdk_version = '7.1'",
        ")",
        "",
        "xcode_version(",
        "    name = 'version64',",
        "    version = '6.4',",
        "    aliases = ['6.0', 'foo', '6'],",
        "    default_ios_sdk_version = '101',",
        "    default_watchos_sdk_version = '102',",
        "    default_tvos_sdk_version = '103',",
        "    default_macos_sdk_version = '104',",
        ")");
    useConfiguration(
        "--xcode_version=6",
        "--xcode_version_config=//xcode:foo",
        "--ios_sdk_version=15.3",
        "--watchos_sdk_version=15.4",
        "--tvos_sdk_version=15.5",
        "--macos_sdk_version=15.6");

    assertXcodeVersion("6.4");
    assertAvailability(XcodeConfigInfo.Availability.UNKNOWN);
    ImmutableMap<ApplePlatform, String> platformToVersion =
        ImmutableMap.<ApplePlatform, String>builder()
            .put(ApplePlatform.IOS_SIMULATOR, "15.3")
            .put(ApplePlatform.WATCHOS_SIMULATOR, "15.4")
            .put(ApplePlatform.TVOS_SIMULATOR, "15.5")
            .put(ApplePlatform.MACOS, "15.6")
            .build();
    for (ApplePlatform platform : platformToVersion.keySet()) {
      DottedVersion version = DottedVersion.fromString(platformToVersion.get(platform));
      assertThat(getSdkVersionForPlatform(platform)).isEqualTo(version);
      assertThat(getMinimumOsVersionForPlatform(platform)).isEqualTo(version);
    }
  }

  @Test
  public void testXcodeVersionFromStarlarkByAlias() throws Exception {
    scratch.file(
        "x/BUILD",
        "load('//x:r.bzl', 'r')",
        "xcode_config_alias(name='a')",
        "xcode_config(name='c', default=':v', versions=[':v'])",
        "xcode_version(",
        "    name = 'v',",
        "    version = '0.0',",
        "    default_ios_sdk_version = '1.0',",
        "    default_tvos_sdk_version = '2.0',",
        "    default_macos_sdk_version = '3.0',",
        "    default_watchos_sdk_version = '4.0',",
        ")",
        "r(name='r')");
    scratch.file(
        "x/r.bzl",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  conf = ctx.attr._xcode[apple_common.XcodeVersionConfig]",
        "  ios = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.ios)",
        "  tvos = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.tvos)",
        "  return MyInfo(",
        "    xcode = conf.xcode_version(),",
        "    ios_sdk = conf.sdk_version_for_platform(ios),",
        "    tvos_sdk = conf.sdk_version_for_platform(tvos),",
        "    macos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.macos),",
        "    watchos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.watchos),",
        "    availability = conf.availability(),",
        "    execution_info = conf.execution_info(),",
        "  )",
        "r = rule(implementation = _impl,",
        "    attrs = { '_xcode': attr.label(default = Label('//x:a'))},",
        "    fragments = ['apple'],",
        ")");

    useConfiguration(
        "--xcode_version_config=//x:c", "--tvos_sdk_version=2.5", "--watchos_minimum_os=4.5");
    ConfiguredTarget r = getConfiguredTarget("//x:r");
    Provider.Key key = new StarlarkProvider.Key(Label.parseCanonical("//x:r.bzl"), "MyInfo");
    StructImpl info = (StructImpl) r.get(key);

    assertThat(info.getValue("xcode").toString()).isEqualTo("0.0");
    assertThat(info.getValue("ios_sdk").toString()).isEqualTo("1.0");
    assertThat(info.getValue("tvos_sdk").toString()).isEqualTo("2.5");
    assertThat(info.getValue("macos_min").toString()).isEqualTo("3.0");
    assertThat(info.getValue("watchos_min").toString()).isEqualTo("4.5");
    assertThat(info.getValue("availability").toString()).isEqualTo("unknown");
    assertThat((Map<?, ?>) info.getValue("execution_info"))
        .containsKey(ExecutionRequirements.REQUIRES_DARWIN);
    assertThat((Map<?, ?>) info.getValue("execution_info"))
        .containsKey(ExecutionRequirements.REQUIREMENTS_SET);
  }

  @Test
  public void testMutualXcodeFromStarlarkByAlias() throws Exception {
    scratch.file(
        "x/BUILD",
        "load('//x:r.bzl', 'r')",
        "xcode_config_alias(name='a')",
        "xcode_config(name='c',",
        "    remote_versions = ':remote',",
        "    local_versions = ':local',",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        ")",
        "xcode_version(",
        "    name = 'version84',",
        "    version = '8.4',",
        ")",
        "available_xcodes(",
        "    name = 'remote',",
        "    versions = [':version512', ':version84'],",
        "    default = ':version512',",
        ")",
        "available_xcodes(",
        "    name = 'local',",
        "    versions = [':version84',],",
        "    default = ':version84',",
        ")",
        "r(name='r')");
    scratch.file(
        "x/r.bzl",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  conf = ctx.attr._xcode[apple_common.XcodeVersionConfig]",
        "  ios = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.ios)",
        "  tvos = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.tvos)",
        "  return MyInfo(",
        "    xcode = conf.xcode_version(),",
        "    ios_sdk = conf.sdk_version_for_platform(ios),",
        "    tvos_sdk = conf.sdk_version_for_platform(tvos),",
        "    macos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.macos),",
        "    watchos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.watchos),",
        "    availability = conf.availability(),",
        "    execution_info = conf.execution_info(),",
        "  )",
        "r = rule(implementation = _impl,",
        "    attrs = { '_xcode': attr.label(default = Label('//x:a'))},",
        "    fragments = ['apple'],",
        ")");

    useConfiguration("--xcode_version_config=//x:c");
    ConfiguredTarget r = getConfiguredTarget("//x:r");
    Provider.Key key = new StarlarkProvider.Key(Label.parseCanonical("//x:r.bzl"), "MyInfo");
    StructImpl info = (StructImpl) r.get(key);
    assertThat((Map<?, ?>) info.getValue("execution_info"))
        .containsKey(ExecutionRequirements.REQUIRES_DARWIN);
    assertThat((Map<?, ?>) info.getValue("execution_info"))
        .containsKey(ExecutionRequirements.REQUIREMENTS_SET);
  }

  @Test
  public void testLocalXcodeFromStarlarkByAlias() throws Exception {
    scratch.file(
        "x/BUILD",
        "load('//x:r.bzl', 'r')",
        "xcode_config_alias(name='a')",
        "xcode_config(name='c',",
        "    remote_versions = ':remote',",
        "    local_versions = ':local',",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1'],",
        ")",
        "xcode_version(",
        "    name = 'version84',",
        "    version = '8.4',",
        ")",
        "available_xcodes(",
        "    name = 'remote',",
        "    versions = [':version512'],",
        "    default = ':version512',",
        ")",
        "available_xcodes(",
        "    name = 'local',",
        "    versions = [':version84',],",
        "    default = ':version84',",
        ")",
        "r(name='r')");
    scratch.file(
        "x/r.bzl",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  conf = ctx.attr._xcode[apple_common.XcodeVersionConfig]",
        "  ios = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.ios)",
        "  tvos = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.tvos)",
        "  return MyInfo(",
        "    xcode = conf.xcode_version(),",
        "    ios_sdk = conf.sdk_version_for_platform(ios),",
        "    tvos_sdk = conf.sdk_version_for_platform(tvos),",
        "    macos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.macos),",
        "    watchos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.watchos),",
        "    availability = conf.availability(),",
        "  )",
        "r = rule(implementation = _impl,",
        "    attrs = { '_xcode': attr.label(default = Label('//x:a'))},",
        "    fragments = ['apple'],",
        ")");

    useConfiguration("--xcode_version_config=//x:c");
    ConfiguredTarget r = getConfiguredTarget("//x:r");
    Provider.Key key = new StarlarkProvider.Key(Label.parseCanonical("//x:r.bzl"), "MyInfo");
    StructImpl info = (StructImpl) r.get(key);

    assertThat(info.getValue("xcode").toString()).isEqualTo("8.4");
    assertThat(info.getValue("availability").toString()).isEqualTo("local");
  }

  @Test
  public void testDefaultWithoutVersion() throws Exception {
    scratch.file(
        "xcode/BUILD",
        "xcode_config(",
        "    name = 'foo',",
        "    default = ':version512',",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1', '5.1.2'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent(
        "default label '//xcode:version512' must be contained in versions attribute");
  }

  @Test
  public void testVersionDoesNotContainDefault() throws Exception {
    scratch.file(
        "xcode/BUILD",
        "xcode_config(",
        "    name = 'foo',",
        "    default = ':version512',",
        "    versions = [':version6'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version512',",
        "    version = '5.1.2',",
        "    aliases = ['5', '5.1', '5.1.2'],",
        ")",
        "",
        "xcode_version(",
        "    name = 'version6',",
        "    version = '6.0',",
        ")");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent("must be contained in versions attribute");
  }

  // Verifies that the --xcode_version_config configuration value can be accessed via the
  // configuration_field() Starlark method and used in a Starlark rule.
  @Test
  public void testConfigurationFieldForRule() throws Exception {
    scratch.file(
        "x/provider_grabber.bzl",
        "def _impl(ctx):",
        "  conf = ctx.attr._xcode_dep[apple_common.XcodeVersionConfig]",
        "  return [conf]",
        "provider_grabber = rule(implementation = _impl,",
        "    attrs = { '_xcode_dep': attr.label(",
        "        default = configuration_field(",
        "            fragment = 'apple', name = 'xcode_config_label')),",
        "    },",
        "    fragments = ['apple'],",
        ")");

    scratch.file(
        "x/BUILD",
        "load('//x:provider_grabber.bzl', 'provider_grabber')",
        "xcode_config(name='config1', default=':version1', versions=[':version1'])",
        "xcode_config(name='config2', default=':version2', versions=[':version2'])",
        "xcode_version(name = 'version1', version = '1.0')",
        "xcode_version(name = 'version2', version = '2.0')",
        "provider_grabber(name='provider_grabber')");

    useConfiguration("--xcode_version_config=//x:config1");
    assertXcodeVersion("1.0", "//x:provider_grabber");

    useConfiguration("--xcode_version_config=//x:config2");
    assertXcodeVersion("2.0", "//x:provider_grabber");
  }

  // Verifies that the --xcode_version_config configuration value can be accessed via the
  // configuration_field() Starlark method and used in a Starlark aspect.
  @Test
  public void testConfigurationFieldForAspect() throws Exception {
    scratch.file(
        "x/provider_grabber.bzl",
        "def _aspect_impl(target, ctx):",
        "  conf = ctx.attr._xcode_dep[apple_common.XcodeVersionConfig]",
        "  return [conf]",
        "",
        "MyAspect = aspect(implementation = _aspect_impl,",
        "    attrs = { '_xcode_dep': attr.label(",
        "        default = configuration_field(",
        "            fragment = 'apple', name = 'xcode_config_label')),",
        "    },",
        "    fragments = ['apple'],",
        ")",
        "",
        "def _rule_impl(ctx):",
        "  conf = ctx.attr.dep[0][apple_common.XcodeVersionConfig]",
        "  return [conf]",
        "",
        "provider_grabber = rule(implementation = _rule_impl,",
        "    attrs = { 'dep' : ",
        "             attr.label_list(mandatory=True, allow_files=True, aspects = [MyAspect]) },",
        ")");

    scratch.file(
        "x/BUILD",
        "load('//x:provider_grabber.bzl', 'provider_grabber')",
        "xcode_config(name='config1', default=':version1', versions=[':version1'])",
        "xcode_config(name='config2', default=':version2', versions=[':version2'])",
        "xcode_version(name = 'version1', version = '1.0')",
        "xcode_version(name = 'version2', version = '2.0')",
        "java_library(",
        "     name = 'fake_lib',",
        ")",
        "provider_grabber(",
        "     name = 'provider_grabber',",
        "     dep = [':fake_lib'],",
        ")");

    useConfiguration("--xcode_version_config=//x:config1");
    assertXcodeVersion("1.0", "//x:provider_grabber");

    useConfiguration("--xcode_version_config=//x:config2");
    assertXcodeVersion("2.0", "//x:provider_grabber");
  }

  @Test
  public void testExplicitXcodesModeNoFlag() throws Exception {
    new BuildFileBuilder()
        .addExplicitVersion("version512", "5.1.2", true, "5", "5.1")
        .addExplicitVersion("version64", "6.4", false, "6.0", "foo", "6")
        .write(scratch, "xcode/BUILD");
    getConfiguredTarget("//xcode:foo");
    XcodeConfigRuleInfo expected =
        XcodeConfigRuleInfo.newBuilder()
            .setSelectedVersion("5.1.2")
            .setDefaultVersion("5.1.2")
            .setSelectedVersionAvailability(Availability.UNKNOWN)
            .addExplicitVersions(
                XcodeVersionInfo.newBuilder()
                    .setVersion("5.1.2")
                    .addAllAliases(ImmutableList.of("5", "5.1")))
            .addExplicitVersions(
                XcodeVersionInfo.newBuilder()
                    .setVersion("6.4")
                    .addAllAliases(ImmutableList.of("6.0", "foo", "6")))
            .build();
    assertThat(eventRecorder.xcodeConfigEvent.xcodeConfigInfo).isEqualTo(expected);
  }

  @Test
  public void testExplicitXcodesModeWithFlag() throws Exception {
    new BuildFileBuilder()
        .addExplicitVersion("version512", "5.1.2", true, "5", "5.1")
        .addExplicitVersion("version64", "6.4", false, "6.0", "foo", "6")
        .write(scratch, "xcode/BUILD");
    useConfiguration("--xcode_version=6.4");
    getConfiguredTarget("//xcode:foo");
    XcodeConfigRuleInfo expected =
        XcodeConfigRuleInfo.newBuilder()
            .setSelectedVersion("6.4")
            .setDefaultVersion("5.1.2")
            .setSelectedVersionAvailability(Availability.UNKNOWN)
            .addExplicitVersions(
                XcodeVersionInfo.newBuilder()
                    .setVersion("5.1.2")
                    .addAllAliases(ImmutableList.of("5", "5.1")))
            .addExplicitVersions(
                XcodeVersionInfo.newBuilder()
                    .setVersion("6.4")
                    .addAllAliases(ImmutableList.of("6.0", "foo", "6")))
            .setXcodeVersionFlag("6.4")
            .build();
    assertThat(eventRecorder.xcodeConfigEvent.xcodeConfigInfo).isEqualTo(expected);
  }

  @Test
  public void testAvailableXcodesModeNoFlag() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version512", "5.1.2", true, "5", "5.1")
        .addRemoteVersion("version84", "8.4", false)
        .addLocalVersion("version84", "8.4", true)
        .write(scratch, "xcode/BUILD");

    useConfiguration("--xcode_version_config=//xcode:foo");
    getConfiguredTarget("//xcode:foo");
    XcodeConfigRuleInfo expected =
        XcodeConfigRuleInfo.newBuilder()
            .setSelectedVersion("8.4")
            .setDefaultVersion("8.4")
            .setSelectedVersionAvailability(Availability.BOTH)
            .addRemoteVersions(
                XcodeVersionInfo.newBuilder()
                    .setVersion("5.1.2")
                    .addAllAliases(ImmutableList.of("5", "5.1")))
            .addRemoteVersions(XcodeVersionInfo.newBuilder().setVersion("8.4"))
            .addLocalVersions(XcodeVersionInfo.newBuilder().setVersion("8.4"))
            .addMutualVersions(XcodeVersionInfo.newBuilder().setVersion("8.4"))
            .build();
    assertThat(eventRecorder.xcodeConfigEvent.xcodeConfigInfo).isEqualTo(expected);
  }

  @Test
  public void testAvailableXcodeModesDifferentAlias() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version5", "5.1", true, "5")
        .addLocalVersion("version5.1.2", "5.1.2", true, "5")
        .write(scratch, "xcode/BUILD");
    useConfiguration("--xcode_version=5");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent("Xcode version 5 was selected");
    assertContainsEvent("This corresponds to local Xcode version 5.1.2");
  }

  @Test
  public void testAvailableXcodeModesDifferentAliasFullySpecified() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version5", "5.1", true, "5")
        .addLocalVersion("version5.1.2", "5.1.2", true, "5")
        .write(scratch, "xcode/BUILD");
    useConfiguration("--xcode_version=5.1.2");
    getConfiguredTarget("//xcode:foo");
    assertXcodeVersion("5.1.2");
    assertAvailability(XcodeConfigInfo.Availability.LOCAL);
  }

  @Test
  public void testAvailableXcodesModeWithFlag() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version512", "5.1.2", true, "5", "5.1")
        .addRemoteVersion("version84", "8.4", false)
        .addLocalVersion("version84", "8.4", true)
        .write(scratch, "xcode/BUILD");
    useConfiguration("--xcode_version=5.1.2");
    getConfiguredTarget("//xcode:foo");
    XcodeConfigRuleInfo expected =
        XcodeConfigRuleInfo.newBuilder()
            .setSelectedVersion("5.1.2")
            .setDefaultVersion("8.4")
            .setSelectedVersionAvailability(Availability.REMOTE)
            .addRemoteVersions(
                XcodeVersionInfo.newBuilder()
                    .setVersion("5.1.2")
                    .addAllAliases(ImmutableList.of("5", "5.1")))
            .addRemoteVersions(XcodeVersionInfo.newBuilder().setVersion("8.4"))
            .addLocalVersions(XcodeVersionInfo.newBuilder().setVersion("8.4"))
            .addMutualVersions(XcodeVersionInfo.newBuilder().setVersion("8.4"))
            .setXcodeVersionFlag("5.1.2")
            .build();
    assertThat(this.eventRecorder.xcodeConfigEvent.xcodeConfigInfo).isEqualTo(expected);
  }

  @Test
  public void testXcodeWithExtensionMatchingRemote() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version0", "0.0", true, "0.0-unstable")
        .addLocalVersion("version84", "8.4", true)
        .write(scratch, "xcode/BUILD");
    useConfiguration(
        "--xcode_version=0.0-unstable", "--experimental_include_xcode_execution_requirements=true");
    getConfiguredTarget("//xcode:foo");

    assertAvailability(XcodeConfigInfo.Availability.REMOTE);
    assertHasRequirementsWithValues(
        ImmutableMap.of(
            ExecutionRequirements.REQUIRES_XCODE + ":0.0", "",
            ExecutionRequirements.REQUIRES_XCODE_LABEL + ":unstable", ""));
  }

  @Test
  public void testXcodeVersionWithExtensionMatchingRemoteAndLocal() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version0.x", "0.0", true, "0.0-unstable")
        .addLocalVersion("version0", "0.0", true, "0.0", "0.0.1")
        .write(scratch, "xcode/BUILD");
    useConfiguration(
        "--xcode_version=0.0-unstable", "--experimental_include_xcode_execution_requirements=true");
    getConfiguredTarget("//xcode:foo");

    assertAvailability(XcodeConfigInfo.Availability.REMOTE);
    assertHasRequirementsWithValues(
        ImmutableMap.of(
            ExecutionRequirements.REQUIRES_XCODE + ":0.0", "",
            ExecutionRequirements.REQUIRES_XCODE_LABEL + ":unstable", ""));
  }

  @Test
  public void testXcodeVersionWithNoExtension() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version00-remote", "0.0", true, "0.0", "0.0-beta")
        .addLocalVersion("version00", "0.0", true, "0.0")
        .write(scratch, "xcode/BUILD");
    useConfiguration(
        "--xcode_version=0.0", "--experimental_include_xcode_execution_requirements=true");
    getConfiguredTarget("//xcode:foo");

    assertAvailability(XcodeConfigInfo.Availability.BOTH);
    assertHasRequirementsWithValues(
        ImmutableMap.of(ExecutionRequirements.REQUIRES_XCODE + ":0.0", ""));
    assertDoesNotHaveRequirements(
        ImmutableList.of(ExecutionRequirements.REQUIRES_XCODE_LABEL + ":"));
  }

  private DottedVersion getSdkVersionForPlatform(ApplePlatform platform) throws Exception {
    ConfiguredTarget xcodeConfig = getConfiguredTarget("//xcode:foo");
    XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER);
    return provider.getSdkVersionForPlatform(platform);
  }

  private DottedVersion getMinimumOsVersionForPlatform(ApplePlatform platform) throws Exception {
    ConfiguredTarget xcodeConfig = getConfiguredTarget("//xcode:foo");
    XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER);
    return provider.getMinimumOsForPlatformType(platform.getType());
  }

  private void assertXcodeVersion(String version) throws Exception {
    assertXcodeVersion(version, "//xcode:foo");
  }

  private void assertXcodeVersion(String version, String providerTargetLabel) throws Exception {
    ConfiguredTarget xcodeConfig = getConfiguredTarget(providerTargetLabel);
    XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER);
    assertThat(provider.getXcodeVersion()).isEqualTo(DottedVersion.fromString(version));
  }

  private void assertAvailability(XcodeConfigInfo.Availability availability) throws Exception {
    assertAvailability(availability, "//xcode:foo");
  }

  private void assertAvailability(
      XcodeConfigInfo.Availability availability, String providerTargetLabel) throws Exception {
    ConfiguredTarget xcodeConfig = getConfiguredTarget(providerTargetLabel);
    XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER);
    assertThat(provider.getAvailability()).isEqualTo(availability);
  }

  private void assertHasRequirements(List<String> executionRequirements) throws Exception {
    assertHasRequirements(executionRequirements, "//xcode:foo");
  }

  private void assertHasRequirements(List<String> executionRequirements, String providerTargetLabel)
      throws Exception {
    ConfiguredTarget xcodeConfig = getConfiguredTarget(providerTargetLabel);
    XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER);
    for (String requirement : executionRequirements) {
      assertThat(requirement).isIn(provider.getExecutionRequirements().keySet());
    }
  }

  private void assertDoesNotHaveRequirements(List<String> executionRequirements) throws Exception {
    assertDoesNotHaveRequirements(executionRequirements, "//xcode:foo");
  }

  private void assertDoesNotHaveRequirements(
      List<String> executionRequirements, String providerTargetLabel) throws Exception {
    ConfiguredTarget xcodeConfig = getConfiguredTarget(providerTargetLabel);
    XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER);
    for (String requirement : executionRequirements) {
      assertThat(requirement).isNotIn(provider.getExecutionRequirements().keySet());
    }
  }

  private void assertHasRequirementsWithValues(Map<String, String> executionRequirements)
      throws Exception {
    assertHasRequirementsWithValues(executionRequirements, "//xcode:foo");
  }

  private void assertHasRequirementsWithValues(
      Map<String, String> executionRequirements, String providerTargetLabel) throws Exception {
    ConfiguredTarget xcodeConfig = getConfiguredTarget(providerTargetLabel);
    XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER);
    for (Map.Entry<String, String> requirement : executionRequirements.entrySet()) {
      assertThat(requirement.getKey()).isIn(provider.getExecutionRequirements().keySet());
      assertThat(provider.getExecutionRequirements().getOrDefault(requirement.getKey(), ""))
          .isEqualTo(requirement.getValue());
    }
  }

  private void assertIosSdkVersion(String version) throws Exception {
    assertThat(getSdkVersionForPlatform(ApplePlatform.IOS_SIMULATOR))
        .isEqualTo(DottedVersion.fromString(version));
  }

  /** Returns a ConfiguredAttributeMapper bound to the given rule with the target configuration. */
  private ConfiguredAttributeMapper getMapper(String label) throws Exception {
    ConfiguredTargetAndData ctad = getConfiguredTargetAndData(label);
    return getMapperFromConfiguredTargetAndTarget(ctad);
  }
}
