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