// Copyright 2016 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.cpp;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.CoreOptions;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.ApplePlatform;
import com.google.devtools.build.lib.rules.apple.AppleToolchain;
import com.google.devtools.build.lib.rules.apple.XcodeConfig;
import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
import com.google.devtools.build.lib.rules.cpp.CcToolchain;
import com.google.devtools.build.lib.rules.cpp.CcToolchainVariables;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Implementation for apple_cc_toolchain rule.
 */
public class AppleCcToolchain extends CcToolchain {
  private static final String XCODE_VERSION_KEY = "xcode_version";
  private static final String IOS_SDK_VERSION_KEY = "ios_sdk_version";
  private static final String MACOS_SDK_VERSION_KEY = "macos_sdk_version";
  private static final String TVOS_SDK_VERSION_KEY = "tvos_sdk_version";
  private static final String WATCHOS_SDK_VERSION_KEY = "watchos_sdk_version";
  public static final String SDK_DIR_KEY = "sdk_dir";
  public static final String SDK_FRAMEWORK_DIR_KEY = "sdk_framework_dir";
  public static final String PLATFORM_DEVELOPER_FRAMEWORK_DIR = "platform_developer_framework_dir";
  public static final String VERSION_MIN_KEY = "version_min";

  @VisibleForTesting
  public static final String XCODE_VERSION_OVERRIDE_VALUE_KEY = "xcode_version_override_value";

  @VisibleForTesting
  public static final String APPLE_SDK_VERSION_OVERRIDE_VALUE_KEY =
      "apple_sdk_version_override_value";

  @VisibleForTesting
  public static final String APPLE_SDK_PLATFORM_VALUE_KEY = "apple_sdk_platform_value";

  @Override
  protected AdditionalBuildVariablesComputer getAdditionalBuildVariablesComputer(
      RuleContext ruleContextPossiblyInHostConfiguration) {
    // xcode config is shared between target and host configuration therefore we can use it.
    XcodeConfigProvider xcodeConfig =
        XcodeConfig.getXcodeConfigProvider(ruleContextPossiblyInHostConfiguration);
    return getAdditionalBuildVariablesComputer(xcodeConfig);
  }

  /** Returns {@link AdditionalBuildVariablesComputer} lambda without capturing instance state. */
  private static AdditionalBuildVariablesComputer getAdditionalBuildVariablesComputer(
      XcodeConfigProvider xcodeConfig) {
    return (AdditionalBuildVariablesComputer & Serializable)
        (BuildOptions buildOptions) -> computeCcToolchainVariables(xcodeConfig, buildOptions);
  }

  private static CcToolchainVariables computeCcToolchainVariables(
      XcodeConfigProvider xcodeConfig, BuildOptions buildOptions) {
    AppleConfiguration.Loader appleConfigurationLoader = new AppleConfiguration.Loader();
    AppleConfiguration appleConfiguration = appleConfigurationLoader.create(buildOptions);
    ApplePlatform platform = appleConfiguration.getSingleArchPlatform();
    String cpu = buildOptions.get(CoreOptions.class).cpu;

    Map<String, String> appleEnv = getEnvironmentBuildVariables(xcodeConfig, cpu);
    CcToolchainVariables.Builder variables = CcToolchainVariables.builder();
    variables
        .addStringVariable(
            XCODE_VERSION_KEY, xcodeConfig.getXcodeVersion().toStringWithMinimumComponents(2))
        .addStringVariable(
            IOS_SDK_VERSION_KEY,
            xcodeConfig
                .getSdkVersionForPlatform(ApplePlatform.IOS_SIMULATOR)
                .toStringWithMinimumComponents(2))
        .addStringVariable(
            MACOS_SDK_VERSION_KEY,
            xcodeConfig
                .getSdkVersionForPlatform(ApplePlatform.MACOS)
                .toStringWithMinimumComponents(2))
        .addStringVariable(
            TVOS_SDK_VERSION_KEY,
            xcodeConfig
                .getSdkVersionForPlatform(ApplePlatform.TVOS_SIMULATOR)
                .toStringWithMinimumComponents(2))
        .addStringVariable(
            WATCHOS_SDK_VERSION_KEY,
            xcodeConfig
                .getSdkVersionForPlatform(ApplePlatform.WATCHOS_SIMULATOR)
                .toStringWithMinimumComponents(2))
        .addStringVariable(SDK_DIR_KEY, AppleToolchain.sdkDir())
        .addStringVariable(
            SDK_FRAMEWORK_DIR_KEY, AppleToolchain.sdkFrameworkDir(platform, xcodeConfig))
        .addStringVariable(
            PLATFORM_DEVELOPER_FRAMEWORK_DIR,
            AppleToolchain.platformDeveloperFrameworkDir(platform))
        .addStringVariable(
            XCODE_VERSION_OVERRIDE_VALUE_KEY,
            appleEnv.getOrDefault(AppleConfiguration.XCODE_VERSION_ENV_NAME, ""))
        .addStringVariable(
            APPLE_SDK_VERSION_OVERRIDE_VALUE_KEY,
            appleEnv.getOrDefault(AppleConfiguration.APPLE_SDK_VERSION_ENV_NAME, ""))
        .addStringVariable(
            APPLE_SDK_PLATFORM_VALUE_KEY,
            appleEnv.getOrDefault(AppleConfiguration.APPLE_SDK_PLATFORM_ENV_NAME, ""))
        .addStringVariable(
            VERSION_MIN_KEY,
            xcodeConfig.getMinimumOsForPlatformType(platform.getType()).toString());
    return variables.build();
  }

  private static ImmutableMap<String, String> getEnvironmentBuildVariables(
      XcodeConfigProvider xcodeConfig, String cpu) {
    Map<String, String> builder = new LinkedHashMap<>();
    builder.putAll(AppleConfiguration.getXcodeVersionEnv(xcodeConfig.getXcodeVersion()));
    if (ApplePlatform.isApplePlatform(cpu)) {
      ApplePlatform platform = ApplePlatform.forTargetCpu(cpu);
      builder.putAll(
          AppleConfiguration.appleTargetPlatformEnv(
              platform, xcodeConfig.getSdkVersionForPlatform(platform)));
    }
    return ImmutableMap.copyOf(builder);
  }

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

  @Override
  protected void validateToolchain(RuleContext ruleContext) throws RuleErrorException {
    if (XcodeConfig.getXcodeConfigProvider(ruleContext).getXcodeVersion() == null) {
      ruleContext.throwWithRuleError(
          "Xcode version must be specified to use an Apple CROSSTOOL. If your Xcode version has "
              + "changed recently, verify that \"xcode-select -p\" is correct and then try: "
              + "\"bazel shutdown\" to re-run Xcode configuration");
    }
  }
}
