// 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) NSURL *url;
@end

@implementation XcodeVersionEntry

- (id)initWithVersion:(NSString *)version url:(NSURL *)url {
  if ((self = [super init])) {
    _version = version;
    _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 rangeOfString:@"/Applications/"].location != NSNotFound;
  NSString *entryVersion = entry.version;
  NSString *subversion = entryVersion;
  if (dict[entryVersion] && !inApplications) {
    return;
  }
  dict[entryVersion] = 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]
                             == 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"];

    // macOS 10.13 changed the signature of initWithContentsOfURL,
    // and deprecated the old one.
    NSDictionary *versionPlistContents;
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_12
    versionPlistContents = [[NSDictionary alloc] initWithContentsOfURL:versionPlistUrl error:nil];
#else
    versionPlistContents = [[NSDictionary alloc] initWithContentsOfURL:versionPlistUrl];
#endif

    NSString *productVersion = [versionPlistContents objectForKey:@"ProductBuildVersion"];
    if (productVersion) {
      expandedVersion = [expandedVersion stringByAppendingFormat:@".%@", productVersion];
    }

    NSURL *developerDir =
        [url URLByAppendingPathComponent:@"Contents/Developer"];
    XcodeVersionEntry *entry =
        [[XcodeVersionEntry alloc] initWithVersion:expandedVersion
                                               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);
  }
}
