// Copyright 2015 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.base.Preconditions.checkState;
import static java.util.stream.Collectors.joining;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;
import com.google.common.flogger.GoogleLogger;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.XcodeConfigEvent;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions.AppleBitcodeMode;
import com.google.devtools.build.lib.rules.apple.XcodeConfigInfo.Availability;
import com.google.devtools.build.lib.xcode.proto.XcodeConfig.XcodeConfigRuleInfo;
import com.google.devtools.build.lib.xcode.proto.XcodeConfig.XcodeVersionInfo;
import java.util.List;
import java.util.Map;
import java.util.Set;

/** Implementation for the {@code xcode_config} rule. */
public class XcodeConfig implements RuleConfiguredTargetFactory {
  private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();

  private static final DottedVersion MINIMUM_BITCODE_XCODE_VERSION =
      DottedVersion.fromStringUnchecked("7");

  /** An exception that signals that an Xcode config setup was invalid. */
  public static class XcodeConfigException extends Exception {

    XcodeConfigException(String reason) {
      super(reason);
    }
  }

  @Override
  public ConfiguredTarget create(RuleContext ruleContext)
      throws InterruptedException, RuleErrorException, ActionConflictException {
    AppleConfiguration appleConfig = ruleContext.getFragment(AppleConfiguration.class);
    AppleCommandLineOptions appleOptions = appleConfig.getOptions();

    XcodeConfigRuleInfo.Builder infoBuilder = XcodeConfigRuleInfo.newBuilder();
    if (appleOptions.xcodeVersion != null) {
      infoBuilder.setXcodeVersionFlag(appleOptions.xcodeVersion);
    }
    XcodeVersionRuleData explicitDefaultVersion =
        ruleContext.getPrerequisite(XcodeConfigRule.DEFAULT_ATTR_NAME, XcodeVersionRuleData.class);

    List<XcodeVersionRuleData> explicitVersions =
        ruleContext.getPrerequisites(
            XcodeConfigRule.VERSIONS_ATTR_NAME, XcodeVersionRuleData.class);

    AvailableXcodesInfo remoteVersions =
        ruleContext.getPrerequisite(
            XcodeConfigRule.REMOTE_VERSIONS_ATTR_NAME,
            AvailableXcodesInfo.PROVIDER);

    AvailableXcodesInfo localVersions =
        ruleContext.getPrerequisite(
            XcodeConfigRule.LOCAL_VERSIONS_ATTR_NAME,
            AvailableXcodesInfo.PROVIDER);

    XcodeVersionProperties xcodeVersionProperties;
    Availability availability = null;
    if (useAvailableXcodesMode(
        explicitVersions, explicitDefaultVersion, localVersions, remoteVersions, ruleContext)) {
      Map.Entry<XcodeVersionRuleData, Availability> xcode =
          resolveXcodeFromLocalAndRemote(
              localVersions,
              remoteVersions,
              ruleContext,
              appleOptions.xcodeVersion,
              appleOptions.preferMutualXcode,
              infoBuilder);
      xcodeVersionProperties = xcode.getKey().getXcodeVersionProperties();
      availability = xcode.getValue();
    } else {
      xcodeVersionProperties =
          resolveExplicitlyDefinedVersion(
              explicitVersions,
              explicitDefaultVersion,
              appleOptions.xcodeVersion,
              ruleContext,
              infoBuilder);
      availability = Availability.UNKNOWN;
    }
    logger.atInfo().log("Using Xcode version %s", xcodeVersionProperties.getXcodeVersionString());
    if (xcodeVersionProperties.getXcodeVersion().isPresent()) {
      infoBuilder
          .setSelectedVersion(xcodeVersionProperties.getXcodeVersionString())
          .setSelectedVersionAvailability(
              XcodeConfigRuleInfo.Availability.valueOf(availability.name()));
    }
    ruleContext
        .getAnalysisEnvironment()
        .getEventHandler()
        .post(new XcodeConfigEvent(infoBuilder.build()));
    DottedVersion iosSdkVersion =
        (appleOptions.iosSdkVersion != null)
            ? DottedVersion.maybeUnwrap(appleOptions.iosSdkVersion)
            : xcodeVersionProperties.getDefaultIosSdkVersion();
    DottedVersion iosMinimumOsVersion =
        (appleOptions.iosMinimumOs != null)
            ? DottedVersion.maybeUnwrap(appleOptions.iosMinimumOs)
            : iosSdkVersion;
    DottedVersion watchosSdkVersion =
        (appleOptions.watchOsSdkVersion != null)
            ? DottedVersion.maybeUnwrap(appleOptions.watchOsSdkVersion)
            : xcodeVersionProperties.getDefaultWatchosSdkVersion();
    DottedVersion watchosMinimumOsVersion =
        (appleOptions.watchosMinimumOs != null)
            ? DottedVersion.maybeUnwrap(appleOptions.watchosMinimumOs)
            : watchosSdkVersion;
    DottedVersion tvosSdkVersion =
        (appleOptions.tvOsSdkVersion != null)
            ? DottedVersion.maybeUnwrap(appleOptions.tvOsSdkVersion)
            : xcodeVersionProperties.getDefaultTvosSdkVersion();
    DottedVersion tvosMinimumOsVersion =
        (appleOptions.tvosMinimumOs != null)
            ? DottedVersion.maybeUnwrap(appleOptions.tvosMinimumOs)
            : tvosSdkVersion;
    DottedVersion macosSdkVersion =
        (appleOptions.macOsSdkVersion != null)
            ? DottedVersion.maybeUnwrap(appleOptions.macOsSdkVersion)
            : xcodeVersionProperties.getDefaultMacosSdkVersion();
    DottedVersion macosMinimumOsVersion =
        (appleOptions.macosMinimumOs != null)
            ? DottedVersion.maybeUnwrap(appleOptions.macosMinimumOs)
            : macosSdkVersion;

    XcodeConfigInfo xcodeVersions =
        new XcodeConfigInfo(
            iosSdkVersion,
            iosMinimumOsVersion,
            watchosSdkVersion,
            watchosMinimumOsVersion,
            tvosSdkVersion,
            tvosMinimumOsVersion,
            macosSdkVersion,
            macosMinimumOsVersion,
            xcodeVersionProperties.getXcodeVersion().orNull(),
            availability);

    AppleBitcodeMode bitcodeMode = appleConfig.getBitcodeMode();
    DottedVersion xcodeVersion = xcodeVersions.getXcodeVersion();
    if (bitcodeMode != AppleBitcodeMode.NONE
        && xcodeVersion != null
        && xcodeVersion.compareTo(MINIMUM_BITCODE_XCODE_VERSION) < 0) {
      ruleContext.throwWithRuleError(
          String.format(
              "apple_bitcode mode '%s' is unsupported for xcode version '%s'",
              bitcodeMode, xcodeVersion));
    }

    return new RuleConfiguredTargetBuilder(ruleContext)
        .addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY)
        .addNativeDeclaredProvider(xcodeVersions)
        .addNativeDeclaredProvider(xcodeVersionProperties)
        .build();
  }

  /**
   * Returns {@code true} if the xcode version will be determined from {@code local_versions} and
   * {@code remote_versions}.
   *
   * @throws RuleErrorException if attributes from both modes have been set.
   */
  private static boolean useAvailableXcodesMode(
      List<XcodeVersionRuleData> explicitVersions,
      XcodeVersionRuleData explicitDefaultVersion,
      AvailableXcodesInfo localVersions,
      AvailableXcodesInfo remoteVersions,
      RuleContext ruleContext)
      throws RuleErrorException {
    if ((remoteVersions != null && !Iterables.isEmpty(remoteVersions.getAvailableVersions()))) {
      if (!explicitVersions.isEmpty()) {
        ruleContext.ruleError("'versions' may not be set if '[local,remote]_versions' is set.");
      }
      if (explicitDefaultVersion != null) {
        ruleContext.ruleError("'default' may not be set if '[local,remote]_versions' is set.");
      }
      if (localVersions == null || Iterables.isEmpty(localVersions.getAvailableVersions())) {
        ruleContext.throwWithRuleError(
            "if 'remote_versions' are set, you must also set 'local_versions'");
      }
      return true;
    }
    return false;
  }
  /**
   * Returns the {@link XcodeVersionProperties} selected by the {@code--xcode_version} flag from the
   * {@code versions} attribute of the {@code xcode_config} target explicitly defined in the {@code
   * --xcode_version_config} build flag. This is not used if the {@code local_versions} or {@code
   * remote_versions} attributes are set. If {@code --xcode_version} is unspecified, then this will
   * return the default rule data as specified in the {@code --xcode_version_config} target.
   *
   * @throws RuleErrorException if required dependencies are missing or ill formatted.
   */
  private static XcodeVersionProperties resolveExplicitlyDefinedVersion(
      List<XcodeVersionRuleData> explicitVersions,
      XcodeVersionRuleData explicitDefaultVersion,
      String versionOverrideFlag,
      RuleContext ruleContext,
      XcodeConfigRuleInfo.Builder infoBuilder)
      throws RuleErrorException {
    if (explicitDefaultVersion != null
        && !Iterables.any(
            explicitVersions,
            ruleData -> ruleData.getLabel().equals(explicitDefaultVersion.getLabel()))) {
      ruleContext.throwWithRuleError(
          String.format(
              "default label '%s' must be contained in versions attribute",
              explicitDefaultVersion.getLabel()));
    }
    if (explicitVersions.isEmpty()) {
      if (explicitDefaultVersion != null) {
        ruleContext.throwWithRuleError("default label must be contained in versions attribute");
      }
      return XcodeVersionProperties.unknownXcodeVersionProperties();
    }
    if (explicitDefaultVersion == null) {
      ruleContext.throwWithRuleError(
          "if any versions are specified, a default version must be specified");
    }
    logger.atInfo().log(
        "Determining Xcode version using single-location Xcodes mode: versions=[%s]",
        printableXcodeVersions(explicitVersions));
    for (XcodeVersionRuleData version : explicitVersions) {
      infoBuilder.addExplicitVersions(
          XcodeVersionInfo.newBuilder()
              .setVersion(version.getVersion().toString())
              .addAllAliases(version.getAliases())
              .build());
    }
    infoBuilder.setDefaultVersion(explicitDefaultVersion.getVersion().toString());

    Map<String, XcodeVersionRuleData> aliasesToVersionMap = null;
    try {
      aliasesToVersionMap = aliasesToVersionMap(explicitVersions);
    } catch (XcodeConfigException e) {
      throw ruleContext.throwWithRuleError(e);
    }

    if (!Strings.isNullOrEmpty(versionOverrideFlag)) {
      // The version override flag is not necessarily an actual version - it may be a version
      // alias.
      XcodeVersionRuleData explicitVersion = aliasesToVersionMap.get(versionOverrideFlag);
      if (explicitVersion != null) {
        return explicitVersion.getXcodeVersionProperties();
      } else {
        ruleContext.throwWithRuleError(
            String.format(
                "--xcode_version=%1$s specified, but '%1$s' is not an available Xcode version. "
                    + "available versions: [%2$s]. If you believe you have '%1$s' installed, try "
                    + "running \"bazel shutdown\", and then re-run your command.",
                versionOverrideFlag, printableXcodeVersions(explicitVersions)));
      }
    }

    return explicitDefaultVersion.getXcodeVersionProperties();
  }

  /**
   * Returns the {@link XcodeVersionRuleData} and availability associated with the {@code
   * xcode_version} target determined from its {@code remote_xcodes} and {@code local_xcodes}
   * dependencies and selected by the {@code --xcode_version} flag. The version specified by {@code
   * --xcode_version} will be used if it's specified and is available locally or remotely (or both).
   * If {@code --xcode_version} is unspecified, then this will return the newest mutually available
   * version if possibls, otherwise the default local version.
   */
  private static Map.Entry<XcodeVersionRuleData, Availability> resolveXcodeFromLocalAndRemote(
      AvailableXcodesInfo localVersions,
      AvailableXcodesInfo remoteVersions,
      RuleContext ruleContext,
      String versionOverrideFlag,
      boolean preferMutualXcode,
      XcodeConfigRuleInfo.Builder infoBuilder)
      throws RuleErrorException {

    Map<String, XcodeVersionRuleData> localAliasesToVersionMap;
    Map<String, XcodeVersionRuleData> remoteAliasesToVersionMap;
    try {
      localAliasesToVersionMap = aliasesToVersionMap(localVersions.getAvailableVersions());
      remoteAliasesToVersionMap = aliasesToVersionMap(remoteVersions.getAvailableVersions());
    } catch (XcodeConfigException e) {
      throw ruleContext.throwWithRuleError(e);
    }
    // Mutually available Xcode versions are versions that are available both locally and remotely,
    // but are referred to by the aliases listed in remote_xcodes.
    Set<XcodeVersionRuleData> mutuallyAvailableVersions = Sets.newHashSet();
    for (String version : localAliasesToVersionMap.keySet()) {
      if (remoteAliasesToVersionMap.containsKey(version)) {
        mutuallyAvailableVersions.add(remoteAliasesToVersionMap.get(version));
      }
    }
    logger.atInfo().log(
        "Determining Xcode version using available Xcodes mode:"
            + " local=[%s], remote=[%s], mutual=[%s]",
        printableXcodeVersions(localVersions.getAvailableVersions()),
        printableXcodeVersions(remoteVersions.getAvailableVersions()),
        printableXcodeVersions(mutuallyAvailableVersions));

    for (XcodeVersionRuleData version : remoteVersions.getAvailableVersions()) {
      infoBuilder.addRemoteVersions(
          XcodeVersionInfo.newBuilder()
              .setVersion(version.getVersion().toString())
              .addAllAliases(version.getAliases()));
    }
    for (XcodeVersionRuleData version : localVersions.getAvailableVersions()) {
      infoBuilder.addLocalVersions(
          XcodeVersionInfo.newBuilder()
              .setVersion(version.getVersion().toString())
              .addAllAliases(version.getAliases()));
    }
    for (XcodeVersionRuleData version : mutuallyAvailableVersions) {
      infoBuilder.addMutualVersions(
          XcodeVersionInfo.newBuilder()
              .setVersion(version.getVersion().toString())
              .addAllAliases(version.getAliases()));
    }
    infoBuilder.setDefaultVersion(localVersions.getDefaultVersion().getVersion().toString());

    if (!Strings.isNullOrEmpty(versionOverrideFlag)) {
      XcodeVersionRuleData specifiedVersionFromRemote =
          remoteAliasesToVersionMap.get(versionOverrideFlag);
      XcodeVersionRuleData specifiedVersionFromLocal =
          localAliasesToVersionMap.get(versionOverrideFlag);
      if (specifiedVersionFromLocal != null && specifiedVersionFromRemote != null) {
        XcodeVersionRuleData strictlyMatchedRemoteVersion =
            remoteAliasesToVersionMap.get(specifiedVersionFromLocal.getVersion().toString());
        if (strictlyMatchedRemoteVersion != null) {
          return Maps.immutableEntry(specifiedVersionFromRemote, Availability.BOTH);
        } else {
          ruleContext.throwWithRuleError(
              String.format(
                  "Xcode version %1$s was selected, either because --xcode_version was passed, or"
                      + " because xcode-select points to this version locally. This corresponds to"
                      + " local Xcode version %2$s. That build of version %1$s is not"
                      + " available remotely, but there is a different build of version %1$s,"
                      + " which has version %3$s and aliases %4$s. You probably meant to use this"
                      + " version. Please download it to continue using dynamic execution. If you"
                      + " really did intend to use local version %2$s, please either specify it"
                      + " fully with --xcode_version=%2$s or disable dynamic (and thus remote)"
                      + " execution.",
                  versionOverrideFlag,
                  specifiedVersionFromLocal.getVersion(),
                  specifiedVersionFromRemote.getVersion(),
                  specifiedVersionFromRemote.getAliases()));
        }
      } else if (specifiedVersionFromLocal != null) {
        String error =
            String.format(
                "--xcode_version=%1$s specified, but it is not available remotely. Actions"
                    + " requiring Xcode will be run locally, which could make your build"
                    + " slower.",
                versionOverrideFlag);
        if (!mutuallyAvailableVersions.isEmpty()) {
          error =
              error
                  + String.format(
                      " Consider using one of [%s].",
                      printableXcodeVersions(mutuallyAvailableVersions));
        }
        ruleContext.ruleWarning(error);
        return Maps.immutableEntry(specifiedVersionFromLocal, Availability.LOCAL);
      } else if (specifiedVersionFromRemote != null) {
        ruleContext.ruleWarning(
            String.format(
                "--xcode_version=%1$s specified, but it is not available locally. Your build"
                    + " will fail if any actions require a local Xcode. If you believe you have"
                    + " '%1$s' installed, try running \"blaze shutdown\", and then re-run your"
                    + " command.  localy available versions: [%2$s]. remotely available"
                    + " versions: [%3$s]",
                versionOverrideFlag,
                printableXcodeVersions(localVersions.getAvailableVersions()),
                printableXcodeVersions(remoteVersions.getAvailableVersions())));
        return Maps.immutableEntry(specifiedVersionFromRemote, Availability.REMOTE);
      } else { // if (specifiedVersionFromRemote == null && specifiedVersionFromLocal == null)
        ruleContext.throwWithRuleError(
            String.format(
                "--xcode_version=%1$s specified, but '%1$s' is not an available Xcode version."
                    + " localy available versions: [%2$s]. remotely available versions:"
                    + " [%3$s]. If you believe you have '%1$s' installed, try running \"blaze"
                    + " shutdown\", and then re-run your command.",
                versionOverrideFlag,
                printableXcodeVersions(localVersions.getAvailableVersions()),
                printableXcodeVersions(remoteVersions.getAvailableVersions())));
      }
    }
    if (preferMutualXcode && !mutuallyAvailableVersions.isEmpty()) {
      DottedVersion newestVersionNumber = DottedVersion.fromStringUnchecked("0.0");
      XcodeVersionRuleData defaultVersion = null;
      for (XcodeVersionRuleData versionRuleData : mutuallyAvailableVersions) {
        if (versionRuleData.getVersion().compareTo(newestVersionNumber) > 0) {
          defaultVersion = versionRuleData;
          newestVersionNumber = defaultVersion.getVersion();
        }
      }
      // This should never occur. All input versions should be above 0.0.
      checkState(defaultVersion != null);
      return Maps.immutableEntry(defaultVersion, Availability.BOTH);
    }
    // Select the local default.
    Availability availability = null;
    XcodeVersionRuleData localVersion = null;
    if (mutuallyAvailableVersions.isEmpty()) {
      ruleContext.ruleWarning(
          String.format(
              "Using a local Xcode version, '%s', since there are no"
                  + " remotely available Xcodes on this machine. Consider downloading one of the"
                  + " remotely available Xcode versions (%s) in order to get the best build"
                  + " performance.",
              localVersions.getDefaultVersion().getVersion(),
              printableXcodeVersions(remoteVersions.getAvailableVersions())));
      localVersion = localVersions.getDefaultVersion();
      availability = Availability.LOCAL;
    } else if (remoteAliasesToVersionMap.containsKey(
        localVersions.getDefaultVersion().getVersion().toString())) {
      availability = Availability.BOTH;
      localVersion =
          remoteAliasesToVersionMap.get(localVersions.getDefaultVersion().getVersion().toString());
    } else {
      for (String versionNumber : localVersions.getDefaultVersion().getAliases()) {
        if (remoteAliasesToVersionMap.containsKey(versionNumber)) {
          availability = Availability.BOTH;
          localVersion = remoteAliasesToVersionMap.get(versionNumber);
          break;
        }
      }
      if (localVersion == null) {
        ruleContext.ruleWarning(
            "You passed --experimental_prefer_mutual_xcode=false, which prevents Bazel from"
                + " selecting an Xcode version that optimizes your performance. Please consider"
                + " using --experimental_prefer_mutual_xcode=true.");
        availability = Availability.LOCAL;
        localVersion = localVersions.getDefaultVersion();
      }
    }
    return Maps.immutableEntry(localVersion, availability);
  }

  private static String printableXcodeVersions(Iterable<XcodeVersionRuleData> xcodeVersions) {
    return Streams.stream(xcodeVersions)
        .map(versionData -> versionData.getVersion().toString())
        .collect(joining(", "));
  }

  /**
   * Returns a map where keys are "names" of xcode versions as defined by the configuration target,
   * and values are the rule data objects which contain information regarding that xcode version.
   *
   * @throws XcodeConfigException if there are duplicate aliases (if two xcode versions were
   *     registered to the same alias)
   */
  private static Map<String, XcodeVersionRuleData> aliasesToVersionMap(
      Iterable<XcodeVersionRuleData> xcodeVersionRules) throws XcodeConfigException {
    Map<String, XcodeVersionRuleData> aliasesToXcodeRules = Maps.newLinkedHashMap();
    if (xcodeVersionRules == null) {
      return aliasesToXcodeRules;
    }
    for (XcodeVersionRuleData xcodeVersionRule : xcodeVersionRules) {
      for (String alias : xcodeVersionRule.getAliases()) {
        if (aliasesToXcodeRules.put(alias, xcodeVersionRule) != null) {
          configErrorDuplicateAlias(alias, xcodeVersionRules);
        }
      }
      // Only add the version as an alias if it's not included in this xcode_version target's
      // aliases (in which case it would have just been added. This offers some leniency in target
      // definition, as it's silly to error if a version is aliased to its own version.
      if (!xcodeVersionRule.getAliases().contains(xcodeVersionRule.getVersion().toString())) {
        if (aliasesToXcodeRules.put(xcodeVersionRule.getVersion().toString(), xcodeVersionRule)
            != null) {
          configErrorDuplicateAlias(xcodeVersionRule.getVersion().toString(), xcodeVersionRules);
        }
      }
    }
    return aliasesToXcodeRules;
  }

  /**
   * Convenience method for throwing an {@link XcodeConfigException} due to presence of duplicate
   * aliases in an {@code xcode_config} target definition.
   */
  private static void configErrorDuplicateAlias(
      String alias, Iterable<XcodeVersionRuleData> xcodeVersionRules) throws XcodeConfigException {

    ImmutableList.Builder<Label> labelsContainingAlias = ImmutableList.builder();
    for (XcodeVersionRuleData xcodeVersionRule : xcodeVersionRules) {
      if (xcodeVersionRule.getAliases().contains(alias)
          || xcodeVersionRule.getVersion().toString().equals(alias)) {
        labelsContainingAlias.add(xcodeVersionRule.getLabel());
      }
    }

    throw new XcodeConfigException(
        String.format(
            "'%s' is registered to multiple labels (%s) in a single xcode_config rule",
            alias, Joiner.on(", ").join(labelsContainingAlias.build())));
  }

  public static XcodeConfigInfo getXcodeConfigInfo(RuleContext ruleContext) {
    return ruleContext.getPrerequisite(
        XcodeConfigRule.XCODE_CONFIG_ATTR_NAME,
        com.google.devtools.build.lib.rules.apple.XcodeConfigInfo.PROVIDER);
  }
}
