// 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 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 testPreferLocalDefaultIfNoMutualNoFlag() 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 testChooseNewestMutualXcode() throws Exception {
    new BuildFileBuilder()
        .addRemoteVersion("version92", "9.2", true)
        .addRemoteVersion("version10", "10", false, "10.0.0.10C504")
        .addRemoteVersion("version84", "8.4", false)
        .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");
    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 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.parseAbsolute("//foo:extension.bzl", ImmutableMap.of()), "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));
  }

  @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.parseAbsolute("//foo:extension.bzl", ImmutableMap.of()), "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.parseAbsolute("//x:r.bzl", ImmutableMap.of()), "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.parseAbsolute("//x:r.bzl", ImmutableMap.of()), "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.parseAbsolute("//x:r.bzl", ImmutableMap.of()), "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");
  }

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

    useConfiguration(
        "--apple_platform_type=ios", "--apple_bitcode=embedded", "--apple_split_cpu=arm64");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//xcode:foo");
    assertContainsEvent("apple_bitcode mode 'embedded' is unsupported");
  }

  // 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);
  }

  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 availabilty) throws Exception {
    assertAvailability(availabilty, "//xcode:foo");
  }

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

  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 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);
  }
}
