// 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.XcodeConfigInfo;
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.
    XcodeConfigInfo xcodeConfig =
        XcodeConfig.getXcodeConfigInfo(ruleContextPossiblyInHostConfiguration);
    return getAdditionalBuildVariablesComputer(xcodeConfig);
  }

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

  private static CcToolchainVariables computeCcToolchainVariables(
      XcodeConfigInfo 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(
      XcodeConfigInfo 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.getXcodeConfigInfo(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");
    }
  }
}
