// Copyright 2015 Google Inc. 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.

// Application that finds all Xcodes installed on a given Mac and will return a
// path for a given version number.
//
// If you have 7.0, 6.4.1 and 6.3 installed the inputs will map to:
//
// 7,7.0,7.0.0 = 7.0
// 6,6.4,6.4.1 = 6.4.1
// 6.3,6.3.0 = 6.3

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

#import <CoreServices/CoreServices.h>
#import <Foundation/Foundation.h>

// Simple data structure for tracking a version of Xcode (i.e. 6.4) with an URL
// to the appplication.
@interface XcodeVersionEntry : NSObject
@property(readonly) NSString *version;
@property(readonly) NSString *productVersion;
@property(readonly) NSURL *url;
@end

@implementation XcodeVersionEntry

- (id)initWithVersion:(NSString *)version
       productVersion:(NSString *)productVersion
                  url:(NSURL *)url {
  if ((self = [super init])) {
    _version = version;
    _productVersion = productVersion;
    _url = url;
  }
  return self;
}

- (id)description {
  return [NSString stringWithFormat:@"<%@ %p>: %@ %@",
                   [self class], self, _version, _url];
}

@end

// Given an entry, insert it into a dictionary that is keyed by versions.
//
// For an entry that is 6.4.1:/Applications/Xcode.app, add it for 6.4.1 and
// optionally add it for 6.4 and 6 if it is "better" than any entry that may
// already be there, where "better" is defined as:
//
// 1. Under /Applications/. (This avoids mounted xcode versions taking
//    precedence over installed versions.)
//
// 2. Not older (at least as high version number).
static void AddEntryToDictionary(
  XcodeVersionEntry *entry,
  NSMutableDictionary<NSString *, XcodeVersionEntry *> *dict) {
  BOOL inApplications = [entry.url.path hasPrefix:@"/Applications/"];
  NSString *entryVersion = entry.version;
  NSString *entryProductVersion = entry.productVersion;
  NSString *subversion = entryVersion;
  if (dict[entryVersion] && !inApplications) {
    return;
  }
  dict[entryVersion] = entry;
  if (entryProductVersion) {
    dict[entryProductVersion] = entry;
  }
  while (YES) {
    NSRange range = [subversion rangeOfString:@"." options:NSBackwardsSearch];
    if (range.length == 0 || range.location == 0) {
      break;
    }
    subversion = [subversion substringToIndex:range.location];
    XcodeVersionEntry *subversionEntry = dict[subversion];
    if (subversionEntry) {
      BOOL atLeastAsLarge =
          ([subversionEntry.version compare:entry.version
                                    options:NSNumericSearch] != NSOrderedDescending);
      if (inApplications && atLeastAsLarge) {
        dict[subversion] = entry;
      }
    } else {
      dict[subversion] = entry;
    }
  }
}

// Given a "version", expand it to at least 3 components by adding .0 as
// necessary.
static NSString *ExpandVersion(NSString *version) {
  NSArray *components = [version componentsSeparatedByString:@"."];
  NSString *appendage = nil;
  if (components.count == 2) {
    appendage = @".0";
  } else if (components.count == 1) {
    appendage = @".0.0";
  }
  if (appendage) {
    version = [version stringByAppendingString:appendage];
  }
  return version;
}

// Searches for all available Xcodes in the system and returns a dictionary that
// maps version identifiers of any form (X, X.Y, and X.Y.Z) to the directory
// where the Xcode bundle lives.
//
// If there is a problem locating the Xcodes, prints one or more error messages
// and returns nil.
static NSMutableDictionary<NSString *, XcodeVersionEntry *> *FindXcodes()
  __attribute((ns_returns_retained)) {
  CFStringRef cfBundleID = CFSTR("com.apple.dt.Xcode");
  NSString *bundleID = (__bridge NSString *)cfBundleID;

  NSMutableDictionary<NSString *, XcodeVersionEntry *> *dict =
      [[NSMutableDictionary alloc] init];
  CFErrorRef cfError;
  NSArray *array = CFBridgingRelease(LSCopyApplicationURLsForBundleIdentifier(
      cfBundleID, &cfError));
  if (array == nil) {
    NSError *nsError = (__bridge NSError *)cfError;
    fprintf(stderr, "error: %s\n", nsError.description.UTF8String);
    return nil;
  }

  // Scan all bundles but delay returning in case of errors until we are
  // done. This is to let us log details about all the bundles that were
  // processed so that a faulty bundle doesn't hide useful information about
  // other bundles that were found.
  BOOL errors = NO;
  for (NSURL *url in array) {
    NSArray *contents = [
      [NSFileManager defaultManager] contentsOfDirectoryAtURL:url
                                   includingPropertiesForKeys:nil
                                                      options:0
                                                        error:nil];
    NSLog(@"Found bundle %@ in %@; contents on disk: %@",
          bundleID, url, contents);

    NSBundle *bundle = [NSBundle bundleWithURL:url];
    if (bundle == nil) {
      NSLog(@"ERROR: Unable to open bundle at URL: %@\n", url);
      errors = YES;
      continue;
    }

    // LSCopyApplicationURLsForBundleIdentifier seems to sometimes return
    // invalid bundles (e.g. an arbitrary folder), which we should ignore (but
    // don't treat as an error).
    //
    // To work around this issue, we double check to make sure the NSBundle's
    // bundleIdentifier is that of Xcode's, as invalid bundles won't match.
    if (![bundle.bundleIdentifier isEqualToString:bundleID]) {
      NSLog(@"WARNING: Ignoring bundle %@ due to bundleID mismatch "
            @"(got \"%@\" but expected \"%@\"); info: %@",
            url, bundle.bundleIdentifier, bundleID, bundle.infoDictionary);
      continue;
    }

    NSString *versionKey = @"CFBundleShortVersionString";
    NSString *version = [bundle.infoDictionary objectForKey:versionKey];
    if (version == nil) {
      NSLog(@"ERROR: Cannot find %@ in info for bundle %@; info: %@\n",
            versionKey, url, bundle.infoDictionary);
      errors = YES;
      continue;
    }
    NSString *expandedVersion = ExpandVersion(version);
    NSLog(@"Version strings for %@: short=%@, expanded=%@",
          url, version, expandedVersion);

    NSURL *versionPlistUrl = [url URLByAppendingPathComponent:@"Contents/version.plist"];
    NSDictionary *versionPlistContents =
        [[NSDictionary alloc] initWithContentsOfURL:versionPlistUrl];
    NSString *productVersion = [versionPlistContents objectForKey:@"ProductBuildVersion"];
    if (productVersion) {
      expandedVersion = [expandedVersion stringByAppendingFormat:@".%@", productVersion];
    }

    NSURL *developerDir =
        [url URLByAppendingPathComponent:@"Contents/Developer"];
    XcodeVersionEntry *entry = [[XcodeVersionEntry alloc] initWithVersion:expandedVersion
                                                           productVersion:productVersion
                                                                      url:developerDir];
    AddEntryToDictionary(entry, dict);
  }
  return errors ? nil : dict;
}

// Prints out the located Xcodes as a set of lines where each line contains the
// list of versions for a given Xcode and its location on disk.
static void DumpAsVersionsOnly(
  FILE *output,
  NSMutableDictionary<NSString *, XcodeVersionEntry *> *dict) {
  NSMutableDictionary<NSString *, NSMutableSet <NSString *> *> *aliasDict =
      [[NSMutableDictionary alloc] init];
  [dict enumerateKeysAndObjectsUsingBlock:^(NSString *aliasVersion,
                                            XcodeVersionEntry *entry,
                                            BOOL *stop) {
    NSString *versionString = entry.version;
    if (aliasDict[versionString] == nil) {
      aliasDict[versionString] = [[NSMutableSet alloc] init];
    }
    [aliasDict[versionString] addObject:aliasVersion];
  }];
  for (NSString *version in aliasDict) {
    XcodeVersionEntry *entry = dict[version];
    fprintf(output, "%s:%s:%s\n",
            version.UTF8String,
            [[aliasDict[version] allObjects]
                   componentsJoinedByString: @","].UTF8String,
            entry.url.fileSystemRepresentation);
  }
}

// Prints out the located Xcodes in JSON format.
static void DumpAsJson(
  FILE *output,
  NSMutableDictionary<NSString *, XcodeVersionEntry *> *dict) {
  fprintf(output, "{\n");
  for (NSString *version in dict) {
    XcodeVersionEntry *entry = dict[version];
    fprintf(output, "\t\"%s\": \"%s\",\n",
            version.UTF8String, entry.url.fileSystemRepresentation);
  }
  fprintf(output, "}\n");
}

// Dumps usage information.
static void usage(FILE *output) {
  fprintf(
      output,
      "xcode-locator [-v|<version_number>]"
      "\n\n"
      "Given a version number or partial version number in x.y.z format, "
      "will attempt to return the path to the appropriate developer "
      "directory."
      "\n\n"
      "Omitting a version number will list all available versions in JSON "
      "format, alongside their paths."
      "\n\n"
      "Passing -v will list all available fully-specified version numbers "
      "along with their possible aliases and their developer directory, "
      "each on a new line. For example:"
      "\n\n"
      "7.3.1:7,7.3,7.3.1:/Applications/Xcode.app/Contents/Developer"
      "\n");
}

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSString *versionArg = nil;
    BOOL versionsOnly = NO;
    if (argc == 1) {
      versionArg = @"";
    } else if (argc == 2) {
      NSString *firstArg = [NSString stringWithUTF8String:argv[1]];
      if ([@"-v" isEqualToString:firstArg]) {
        versionsOnly = YES;
        versionArg = @"";
      } else {
        versionArg = firstArg;
      }
    }
    if (versionArg == nil) {
      usage(stderr);
      return 1;
    }

    NSMutableDictionary<NSString *, XcodeVersionEntry *> *dict = FindXcodes();
    if (dict == nil) {
      return 1;
    }

    XcodeVersionEntry *entry = [dict objectForKey:versionArg];
    if (entry) {
      printf("%s\n", entry.url.fileSystemRepresentation);
      return 0;
    }

    if (versionsOnly) {
      DumpAsVersionsOnly(stdout, dict);
    } else {
      DumpAsJson(stdout, dict);
    }
    return ([@"" isEqualToString:versionArg] ? 0 : 1);
  }
}
