// Copyright 2021 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.objc;

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

import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.PlatformOptions;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.platform.ConstraintSettingInfo;
import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
import com.google.devtools.build.lib.analysis.platform.DeclaredToolchainInfo;
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.analysis.platform.PlatformProviderUtils;
import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.util.MockObjcSupport;
import com.google.devtools.build.lib.testutil.TestConstants;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Test case for the use of Apple platforms and the macOS crosstool. */
@RunWith(JUnit4.class)
public class ApplePlatformsToolchainSelectionTest extends ObjcRuleTestCase {

  @Override
  protected boolean platformBasedToolchains() {
    return true;
  }

  private static final ConstraintSettingInfo CPU_CONSTRAINT =
      ConstraintSettingInfo.create(Label.parseAbsoluteUnchecked(
          TestConstants.CONSTRAINTS_PACKAGE_ROOT + "cpu:cpu"));

  private static final ConstraintSettingInfo OS_CONSTRAINT =
      ConstraintSettingInfo.create(Label.parseAbsoluteUnchecked(
          TestConstants.CONSTRAINTS_PACKAGE_ROOT + "os:os"));

  private static final ToolchainTypeInfo CPP_TOOLCHAIN_TYPE =
      ToolchainTypeInfo.create(Label.parseAbsoluteUnchecked(
          TestConstants.TOOLS_REPOSITORY + "//tools/cpp:toolchain_type"));

  private static final String EXTRA_SDK_TOOLCHAINS_FLAG =
      "--extra_toolchains=//tools/build_defs/apple/toolchains:all";

  @Test
  public void testMacOsToolchainSetup() throws Exception {
    // Verify the macOS toolchain and its associated cpp toolchain.
    ConfiguredTarget darwinToolchain =
        getConfiguredTarget("//tools/build_defs/apple/toolchains:darwin_x86_64_any");
    assertThat(darwinToolchain).isNotNull();
    DeclaredToolchainInfo darwinToolchainInfo =
        PlatformProviderUtils.declaredToolchainInfo(darwinToolchain);
    assertThat(darwinToolchainInfo).isNotNull();
    assertThat(darwinToolchainInfo.toolchainLabel()).isEqualTo(Label.parseAbsoluteUnchecked(
            "//" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL_DIR + ":cc-compiler-darwin_x86_64"));
    assertThat(darwinToolchainInfo.toolchainType()).isEqualTo(CPP_TOOLCHAIN_TYPE);

    // Verify the macOS platform.
    ConfiguredTarget darwinPlatform = getConfiguredTarget(
        TestConstants.PLATFORM_PACKAGE_ROOT + "/apple:darwin_x86_64");
    PlatformInfo darwinPlatformInfo = PlatformProviderUtils.platform(darwinPlatform);
    assertThat(darwinPlatformInfo).isNotNull();
  }

  @Test
  public void testIosDeviceToolchainSetup() throws Exception {
    // Verify the iOS 64 bit device toolchain and its associated cpp toolchain.
    ConfiguredTarget iosDeviceToolchain =
        getConfiguredTarget("//tools/build_defs/apple/toolchains:ios_arm64_any");
    assertThat(iosDeviceToolchain).isNotNull();
    DeclaredToolchainInfo iosDeviceToolchainInfo =
        PlatformProviderUtils.declaredToolchainInfo(iosDeviceToolchain);
    assertThat(iosDeviceToolchainInfo).isNotNull();
    assertThat(iosDeviceToolchainInfo.toolchainLabel()).isEqualTo(Label.parseAbsoluteUnchecked(
            "//" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL_DIR + ":cc-compiler-ios_arm64"));
    assertThat(iosDeviceToolchainInfo.toolchainType()).isEqualTo(CPP_TOOLCHAIN_TYPE);

    // Verify the iOS 64 bit device platform.
    ConfiguredTarget iosDevicePlatform = getConfiguredTarget(
        TestConstants.PLATFORM_PACKAGE_ROOT + "/apple:ios_arm64");
    PlatformInfo iosDevicePlatformInfo = PlatformProviderUtils.platform(iosDevicePlatform);
    assertThat(iosDevicePlatformInfo).isNotNull();
  }

  @Test
  public void testToolchainSelectionMacOs() throws Exception {
    // TODO(b/210057756): Modify AppleConfiguration such that apple_platform_type is not needed for
    // platforms.
    useConfiguration(
        EXTRA_SDK_TOOLCHAINS_FLAG,
        "--apple_platform_type=macos",
        "--apple_platforms=" + TestConstants.PLATFORM_PACKAGE_ROOT + "/apple:darwin_x86_64",
        "--platforms=" + TestConstants.PLATFORM_PACKAGE_ROOT + "/apple:darwin_x86_64");
    createLibraryTargetWriter("//a:lib").write();

    BuildConfigurationValue config = getAppleCrosstoolConfiguration();
    BuildOptions crosstoolBuildOptions = config.getOptions();
    assertThat(crosstoolBuildOptions.contains(PlatformOptions.class)).isNotNull();
    List<Label> platforms = crosstoolBuildOptions.get(PlatformOptions.class).platforms;
    assertThat(platforms).containsExactly(Label.parseAbsoluteUnchecked(
        TestConstants.PLATFORM_PACKAGE_ROOT + "/apple:darwin_x86_64"));

    ConfiguredTarget darwinPlatform = getConfiguredTarget(platforms.get(0).toString());
    PlatformInfo darwinPlatformInfo = PlatformProviderUtils.platform(darwinPlatform);

    // Verify the OS and CPU constraints.
    ConstraintValueInfo expectedCpuConstraint =
        ConstraintValueInfo.create(
            CPU_CONSTRAINT,
            Label.parseAbsoluteUnchecked(TestConstants.CONSTRAINTS_PACKAGE_ROOT + "cpu:x86_64"));
    assertThat(darwinPlatformInfo.constraints().has(CPU_CONSTRAINT)).isTrue();
    assertThat(darwinPlatformInfo.constraints().get(CPU_CONSTRAINT))
        .isEqualTo(expectedCpuConstraint);

    ConstraintValueInfo expectedOsConstraint =
        ConstraintValueInfo.create(
            OS_CONSTRAINT,
            Label.parseAbsoluteUnchecked(TestConstants.CONSTRAINTS_PACKAGE_ROOT + "os:osx"));
    assertThat(darwinPlatformInfo.constraints().has(OS_CONSTRAINT)).isTrue();
    assertThat(darwinPlatformInfo.constraints().get(OS_CONSTRAINT))
        .isEqualTo(expectedOsConstraint);
  }

  @Test
  public void testToolchainSelectionIosDevice() throws Exception {
    // TODO(b/210057756): Modify AppleConfiguration such that apple_platform_type is not needed for
    // platforms.
    useConfiguration(
        EXTRA_SDK_TOOLCHAINS_FLAG,
        "--apple_platform_type=ios",
        "--apple_platforms=" + TestConstants.PLATFORM_PACKAGE_ROOT + "/apple:ios_arm64",
        "--platforms=" + TestConstants.PLATFORM_PACKAGE_ROOT + "/apple:ios_arm64");
    createLibraryTargetWriter("//a:lib").write();

    BuildConfigurationValue config = getAppleCrosstoolConfiguration();
    BuildOptions crosstoolBuildOptions = config.getOptions();
    assertThat(crosstoolBuildOptions.contains(PlatformOptions.class)).isNotNull();
    List<Label> platforms = crosstoolBuildOptions.get(PlatformOptions.class).platforms;
    assertThat(platforms).containsExactly(Label.parseAbsoluteUnchecked(
        TestConstants.PLATFORM_PACKAGE_ROOT + "/apple:ios_arm64"));

    ConfiguredTarget iosPlatform = getConfiguredTarget(platforms.get(0).toString());
    PlatformInfo iosPlatformInfo = PlatformProviderUtils.platform(iosPlatform);

    // Verify the OS and CPU constraints.
    ConstraintValueInfo expectedCpuConstraint =
        ConstraintValueInfo.create(
            CPU_CONSTRAINT,
            Label.parseAbsoluteUnchecked(TestConstants.CONSTRAINTS_PACKAGE_ROOT + "cpu:arm64"));
    assertThat(iosPlatformInfo.constraints().has(CPU_CONSTRAINT)).isTrue();
    assertThat(iosPlatformInfo.constraints().get(CPU_CONSTRAINT))
        .isEqualTo(expectedCpuConstraint);

    ConstraintValueInfo expectedOsConstraint =
        ConstraintValueInfo.create(
            OS_CONSTRAINT,
            Label.parseAbsoluteUnchecked(TestConstants.CONSTRAINTS_PACKAGE_ROOT + "os:ios"));
    assertThat(iosPlatformInfo.constraints().has(OS_CONSTRAINT)).isTrue();
    assertThat(iosPlatformInfo.constraints().get(OS_CONSTRAINT))
        .isEqualTo(expectedOsConstraint);
  }
}
