/*
 * Copyright 2014-present Facebook, Inc.
 *
 * 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.facebook.buck.apple;

import com.dd.plist.NSArray;
import com.dd.plist.NSDictionary;
import com.dd.plist.NSObject;
import com.dd.plist.NSString;
import com.dd.plist.PropertyListParser;
import com.facebook.buck.log.Logger;
import com.facebook.buck.util.VersionStringComparator;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
import com.google.common.collect.TreeMultimap;

import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Locale;

/**
 * Utility class to discover the location of SDKs contained inside an Xcode
 * installation.
 */
public class AppleSdkDiscovery {

  private static final Logger LOG = Logger.get(AppleSdkDiscovery.class);

  private static final Ordering<AppleSdk> APPLE_SDK_VERSION_ORDERING =
    Ordering
        .from(new VersionStringComparator())
        .onResultOf(new Function<AppleSdk, String>() {
            @Override
            public String apply(AppleSdk appleSdk) {
                return appleSdk.getVersion();
            }
        });

  private static final String DEFAULT_TOOLCHAIN_ID = "com.apple.dt.toolchain.XcodeDefault";

  // Utility class; do not instantiate.
  private AppleSdkDiscovery() { }

  /**
   * Given a path to an Xcode developer directory and a map of
   * (xctoolchain ID: path) pairs as returned by
   * {@link AppleToolchainDiscovery}, walks through the platforms
   * and builds a map of ({@link AppleSdk}: {@link AppleSdkPaths})
   * objects describing the paths to the SDKs inside.
   *
   * The {@link AppleSdk#getName()} strings match the ones displayed by {@code xcodebuild -showsdks}
   * and look like {@code macosx10.9}, {@code iphoneos8.0}, {@code iphonesimulator8.0},
   * etc.
   */
  public static ImmutableMap<AppleSdk, AppleSdkPaths> discoverAppleSdkPaths(
      Path xcodeDir,
      ImmutableMap<String, Path> xcodeToolchainPaths)
      throws IOException {
    Path defaultToolchainPath = xcodeToolchainPaths.get(DEFAULT_TOOLCHAIN_ID);
    if (defaultToolchainPath == null) {
      LOG.debug("Could not find default toolchain %s; skipping discovery.", DEFAULT_TOOLCHAIN_ID);
      return ImmutableMap.of();
    }
    LOG.debug("Searching for Xcode platforms under %s", xcodeDir);

    ImmutableMap.Builder<AppleSdk, AppleSdkPaths> appleSdkPathsBuilder = ImmutableMap.builder();
    Path platforms = xcodeDir.resolve("Platforms");

    if (!Files.exists(platforms)) {
      return appleSdkPathsBuilder.build();
    }

    // We need to find the most recent SDK for each platform so we can
    // make the fall-back SDKs with no version number in their name
    // ("macosx", "iphonesimulator", "iphoneos").
    //
    // To do this, we store a map of (platform: [sdk1, sdk2, ...])
    // pairs where the SDKs for each platform are ordered by version.
    TreeMultimap<ApplePlatform, ImmutableAppleSdk> orderedSdksForPlatform =
        TreeMultimap.create(
            Ordering.natural(),
            APPLE_SDK_VERSION_ORDERING);

    try (DirectoryStream<Path> platformStream = Files.newDirectoryStream(
        platforms,
             "*.platform")) {
      for (Path platformDir : platformStream) {
        LOG.debug("Searching for Xcode SDKs under %s", platformDir);
        Path developerSdksPath = platformDir.resolve("Developer/SDKs");
        try (DirectoryStream<Path> sdkStream = Files.newDirectoryStream(
                 developerSdksPath,
                 "*.sdk")) {
          for (Path sdkDir : sdkStream) {
            LOG.debug("Fetching SDK name for %s", sdkDir);
            if (Files.isSymbolicLink(sdkDir)) {
              continue;
            }

            ImmutableAppleSdk.Builder sdkBuilder = ImmutableAppleSdk.builder();
            if (buildSdkFromPath(sdkDir, sdkBuilder)) {
              ImmutableAppleSdk sdk = sdkBuilder.build();
              LOG.debug("Found SDK %s", sdk);

              ImmutableSet.Builder<Path> toolchainPathsBuilder = ImmutableSet.builder();
              for (String toolchain : sdk.getToolchains()) {
                Path toolchainPath = xcodeToolchainPaths.get(toolchain);
                if (toolchainPath == null) {
                  LOG.debug("Could not find toolchain with ID %s, ignoring", toolchain);
                } else {
                  toolchainPathsBuilder.add(toolchainPath);
                }
              }
              ImmutableSet<Path> toolchainPaths = toolchainPathsBuilder.build();
              ImmutableAppleSdkPaths.Builder xcodePathsBuilder = ImmutableAppleSdkPaths.builder();
              if (toolchainPaths.isEmpty()) {
                LOG.debug(
                    "No toolchains found for SDK %s, falling back to default %s",
                    sdk,
                    defaultToolchainPath);
                xcodePathsBuilder.addToolchainPaths(defaultToolchainPath);
              } else {
                xcodePathsBuilder.addAllToolchainPaths(toolchainPaths);
              }
              ImmutableAppleSdkPaths xcodePaths = xcodePathsBuilder
                  .setDeveloperPath(xcodeDir)
                  .setPlatformDeveloperPath(platformDir.resolve("Developer"))
                  .setSdkPath(sdkDir)
                  .build();
              appleSdkPathsBuilder.put(sdk, xcodePaths);
              orderedSdksForPlatform.put(sdk.getApplePlatform(), sdk);
            }
          }
        } catch (NoSuchFileException e) {
          LOG.warn(
              e,
              "Couldn't discover SDKs at path %s, ignoring platform %s",
              developerSdksPath,
              platformDir);
        }
      }
    }

    // Get a snapshot of what's in appleSdkPathsBuilder, then for each
    // ApplePlatform, add to appleSdkPathsBuilder the most recent
    // SDK with an unversioned name.
    ImmutableMap<AppleSdk, AppleSdkPaths> discoveredSdkPaths = appleSdkPathsBuilder.build();

    for (ApplePlatform platform : orderedSdksForPlatform.keySet()) {
      ImmutableAppleSdk mostRecentSdkForPlatform = orderedSdksForPlatform.get(platform).last();
      appleSdkPathsBuilder.put(
          mostRecentSdkForPlatform.withName(platform.toString()),
          discoveredSdkPaths.get(mostRecentSdkForPlatform));
    }

    // This includes both the discovered SDKs with versions in their names, as well as
    // the unversioned aliases added just above.
    return appleSdkPathsBuilder.build();
  }

  private static void addArchitecturesForPlatform(
      ImmutableAppleSdk.Builder sdkBuilder,
      ApplePlatform applePlatform) {
    // TODO(user): These need to be read from the SDK, not hard-coded.
    switch (applePlatform) {
      case MACOSX:
        // Fall through.
      case IPHONESIMULATOR:
        sdkBuilder.addArchitectures("i386", "x86_64");
        break;
      case IPHONEOS:
        sdkBuilder.addArchitectures("armv7", "arm64");
        break;
    }
  }

  private static boolean buildSdkFromPath(
        Path sdkDir,
        ImmutableAppleSdk.Builder sdkBuilder) throws IOException {
    try (InputStream sdkSettingsPlist = Files.newInputStream(sdkDir.resolve("SDKSettings.plist"));
         BufferedInputStream bufferedSdkSettingsPlist = new BufferedInputStream(sdkSettingsPlist)) {
      NSDictionary sdkSettings;
      try {
        sdkSettings = (NSDictionary) PropertyListParser.parse(bufferedSdkSettingsPlist);
      } catch (Exception e) {
        throw new IOException(e);
      }
      String name = sdkSettings.objectForKey("CanonicalName").toString();
      String version = sdkSettings.objectForKey("Version").toString();
      NSDictionary defaultProperties = (NSDictionary) sdkSettings.objectForKey("DefaultProperties");
      NSArray toolchains = (NSArray) sdkSettings.objectForKey("Toolchains");
      if (toolchains != null) {
        for (NSObject toolchain : toolchains.getArray()) {
          String toolchainId = toolchain.toString();
          sdkBuilder.addToolchains(toolchainId);
        }
      }
      NSString platformName = (NSString) defaultProperties.objectForKey("PLATFORM_NAME");
      // TODO(grp): Generalize this to handle new platforms as they are added.
      ApplePlatform applePlatform;
      try {
        applePlatform = ApplePlatform.valueOf(platformName.toString().toUpperCase(Locale.US));
        sdkBuilder.setName(name).setVersion(version).setApplePlatform(applePlatform);
        addArchitecturesForPlatform(sdkBuilder, applePlatform);
        return true;
      } catch (IllegalArgumentException e) {
        LOG.debug(e, "Ignoring SDK at %s with unrecognized platform %s", sdkDir, platformName);
        return false;
      }
    } catch (FileNotFoundException e) {
      LOG.error(e, "No SDKSettings.plist found under SDK path %s", sdkDir);
      return false;
    }
  }
}
