// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <asl.h>
#import <Foundation/Foundation.h>
#include <libgen.h>
#include <stdarg.h>
#include <stdio.h>

// An executable (iossim) that runs an app in the iOS Simulator.
// Run 'iossim -h' for usage information.
//
// For best results, the iOS Simulator application should not be running when
// iossim is invoked.
//
// Headers for iPhoneSimulatorRemoteClient and other frameworks used in this
// tool are generated by class-dump, via GYP.
// (class-dump is available at http://www.codethecode.com/projects/class-dump/)
//
// However, there are some forward declarations required to get things to
// compile.

// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed
// (crbug.com/385030).
#if defined(IOSSIM_USE_XCODE_6)
@class DVTStackBacktrace;
#import "DVTFoundation.h"
#endif  // IOSSIM_USE_XCODE_6

// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed
// (crbug.com/385030).
#if defined(IOSSIM_USE_XCODE_6)
@protocol SimBridge;
@class DVTSimulatorApplication;
@class SimDeviceSet;
@class SimDeviceType;
@class SimRuntime;
@class SimServiceConnectionManager;
#import "CoreSimulator.h"
#endif  // IOSSIM_USE_XCODE_6

@interface DVTPlatform : NSObject
+ (BOOL)loadAllPlatformsReturningError:(id*)arg1;
@end
@class DTiPhoneSimulatorApplicationSpecifier;
@class DTiPhoneSimulatorSession;
@class DTiPhoneSimulatorSessionConfig;
@class DTiPhoneSimulatorSystemRoot;
@class DVTConfinementServiceConnection;
@class DVTDispatchLock;
@class DVTiPhoneSimulatorMessenger;
@class DVTNotificationToken;
@class DVTTask;
// The DTiPhoneSimulatorSessionDelegate protocol is referenced
// by the iPhoneSimulatorRemoteClient framework, but not defined in the object
// file, so it must be defined here before importing the generated
// iPhoneSimulatorRemoteClient.h file.
@protocol DTiPhoneSimulatorSessionDelegate
- (void)session:(DTiPhoneSimulatorSession*)session
    didEndWithError:(NSError*)error;
- (void)session:(DTiPhoneSimulatorSession*)session
       didStart:(BOOL)started
      withError:(NSError*)error;
@end
#import "DVTiPhoneSimulatorRemoteClient.h"

// An undocumented system log key included in messages from launchd. The value
// is the PID of the process the message is about (as opposed to launchd's PID).
#define ASL_KEY_REF_PID "RefPID"

namespace {

// Name of environment variables that control the user's home directory in the
// simulator.
const char* const kUserHomeEnvVariable = "CFFIXED_USER_HOME";
const char* const kHomeEnvVariable = "HOME";

// Device family codes for iPhone and iPad.
const int kIPhoneFamily = 1;
const int kIPadFamily = 2;

// Max number of seconds to wait for the simulator session to start.
// This timeout must allow time to start up iOS Simulator, install the app
// and perform any other black magic that is encoded in the
// iPhoneSimulatorRemoteClient framework to kick things off. Normal start up
// time is only a couple seconds but machine load, disk caches, etc., can all
// affect startup time in the wild so the timeout needs to be fairly generous.
// If this timeout occurs iossim will likely exit with non-zero status; the
// exception being if the app is invoked and completes execution before the
// session is started (this case is handled in session:didStart:withError).
const NSTimeInterval kDefaultSessionStartTimeoutSeconds = 30;

// While the simulated app is running, its stdout is redirected to a file which
// is polled by iossim and written to iossim's stdout using the following
// polling interval.
const NSTimeInterval kOutputPollIntervalSeconds = 0.1;

NSString* const kDVTFoundationRelativePath =
    @"../SharedFrameworks/DVTFoundation.framework";
NSString* const kDevToolsFoundationRelativePath =
    @"../OtherFrameworks/DevToolsFoundation.framework";
NSString* const kSimulatorRelativePath =
    @"Platforms/iPhoneSimulator.platform/Developer/Applications/"
    @"iPhone Simulator.app";

// Simulator Error String Key. This can be found by looking in the Simulator's
// Localizable.strings files.
NSString* const kSimulatorAppQuitErrorKey = @"The simulated application quit.";

const char* gToolName = "iossim";

// Exit status codes.
const int kExitSuccess = EXIT_SUCCESS;
const int kExitFailure = EXIT_FAILURE;
const int kExitInvalidArguments = 2;
const int kExitInitializationFailure = 3;
const int kExitAppFailedToStart = 4;
const int kExitAppCrashed = 5;
const int kExitUnsupportedXcodeVersion = 6;

void LogError(NSString* format, ...) {
  va_list list;
  va_start(list, format);

  NSString* message =
      [[[NSString alloc] initWithFormat:format arguments:list] autorelease];

  fprintf(stderr, "%s: ERROR: %s\n", gToolName, [message UTF8String]);
  fflush(stderr);

  va_end(list);
}

void LogWarning(NSString* format, ...) {
  va_list list;
  va_start(list, format);

  NSString* message =
      [[[NSString alloc] initWithFormat:format arguments:list] autorelease];

  fprintf(stderr, "%s: WARNING: %s\n", gToolName, [message UTF8String]);
  fflush(stderr);

  va_end(list);
}

// Helper to find a class by name and die if it isn't found.
Class FindClassByName(NSString* nameOfClass) {
  Class theClass = NSClassFromString(nameOfClass);
  if (!theClass) {
    LogError(@"Failed to find class %@ at runtime.", nameOfClass);
    exit(kExitInitializationFailure);
  }
  return theClass;
}

// Returns the a NSString containing the stdout from running an NSTask that
// launches |toolPath| with th given command line |args|.
NSString* GetOutputFromTask(NSString* toolPath, NSArray* args) {
  NSTask* task = [[[NSTask alloc] init] autorelease];
  [task setLaunchPath:toolPath];
  [task setArguments:args];
  NSPipe* outputPipe = [NSPipe pipe];
  [task setStandardOutput:outputPipe];
  NSFileHandle* outputFile = [outputPipe fileHandleForReading];

  [task launch];
  NSData* outputData = [outputFile readDataToEndOfFile];
  [task waitUntilExit];
  if ([task isRunning]) {
    LogError(@"Task '%@ %@' is still running.",
        toolPath,
        [args componentsJoinedByString:@" "]);
    return nil;
  } else if ([task terminationStatus]) {
    LogError(@"Task '%@ %@' exited with return code %d.",
        toolPath,
        [args componentsJoinedByString:@" "],
        [task terminationStatus]);
    return nil;
  }
  return [[[NSString alloc] initWithData:outputData
                                encoding:NSUTF8StringEncoding] autorelease];
}

// Finds the Xcode version via xcodebuild -version. Output from xcodebuild is
// expected to look like:
//   Xcode <version>
//   Build version 5B130a
// where <version> is the string returned by this function (e.g. 6.0).
NSString* FindXcodeVersion() {
  NSString* output = GetOutputFromTask(@"/usr/bin/xcodebuild",
                                       @[ @"-version" ]);
  // Scan past the "Xcode ", then scan the rest of the line into |version|.
  NSScanner* scanner = [NSScanner scannerWithString:output];
  BOOL valid = [scanner scanString:@"Xcode " intoString:NULL];
  NSString* version;
  valid =
      [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet]
                              intoString:&version];
  if (!valid) {
    LogError(@"Unable to find Xcode version. 'xcodebuild -version' "
             @"returned \n%@", output);
    return nil;
  }
  return version;
}

// Returns true if iossim is running with Xcode 6 or later installed on the
// host.
BOOL IsRunningWithXcode6OrLater() {
  static NSString* xcodeVersion = FindXcodeVersion();
  if (!xcodeVersion) {
    return false;
  }
  NSArray* components = [xcodeVersion componentsSeparatedByString:@"."];
  if ([components count] < 1) {
    return false;
  }
  NSInteger majorVersion = [[components objectAtIndex:0] integerValue];
  return majorVersion >= 6;
}

// Prints supported devices and SDKs.
void PrintSupportedDevices() {
  if (IsRunningWithXcode6OrLater()) {
#if defined(IOSSIM_USE_XCODE_6)
    printf("Supported device/SDK combinations:\n");
    Class simDeviceSetClass = FindClassByName(@"SimDeviceSet");
    id deviceSet =
        [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]];
    for (id simDevice in [deviceSet availableDevices]) {
      NSString* deviceInfo =
          [NSString stringWithFormat:@"  -d '%@' -s '%@'\n",
              [simDevice name], [[simDevice runtime] versionString]];
      printf("%s", [deviceInfo UTF8String]);
    }
#endif  // IOSSIM_USE_XCODE_6
  } else {
    printf("Supported SDK versions:\n");
    Class rootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot");
    for (id root in [rootClass knownRoots]) {
      printf("  '%s'\n", [[root sdkVersion] UTF8String]);
    }
    // This is the list of devices supported on Xcode 5.1.x.
    printf("Supported devices:\n");
    printf("  'iPhone'\n");
    printf("  'iPhone Retina (3.5-inch)'\n");
    printf("  'iPhone Retina (4-inch)'\n");
    printf("  'iPhone Retina (4-inch 64-bit)'\n");
    printf("  'iPad'\n");
    printf("  'iPad Retina'\n");
    printf("  'iPad Retina (64-bit)'\n");
  }
}
}  // namespace

// A delegate that is called when the simulated app is started or ended in the
// simulator.
@interface SimulatorDelegate : NSObject <DTiPhoneSimulatorSessionDelegate> {
 @private
  NSString* stdioPath_;
  NSString* developerDir_;
  NSString* simulatorHome_;
  NSThread* outputThread_;
  NSBundle* simulatorBundle_;
  BOOL appRunning_;
}
@end

// An implementation that copies the simulated app's stdio to stdout of this
// executable. While it would be nice to get stdout and stderr independently
// from iOS Simulator, issues like I/O buffering and interleaved output
// between iOS Simulator and the app would cause iossim to display things out
// of order here. Printing all output to a single file keeps the order correct.
// Instances of this classe should be initialized with the location of the
// simulated app's output file. When the simulated app starts, a thread is
// started which handles copying data from the simulated app's output file to
// the stdout of this executable.
@implementation SimulatorDelegate

// Specifies the file locations of the simulated app's stdout and stderr.
- (SimulatorDelegate*)initWithStdioPath:(NSString*)stdioPath
                           developerDir:(NSString*)developerDir
                          simulatorHome:(NSString*)simulatorHome {
  self = [super init];
  if (self) {
    stdioPath_ = [stdioPath copy];
    developerDir_ = [developerDir copy];
    simulatorHome_ = [simulatorHome copy];
  }

  return self;
}

- (void)dealloc {
  [stdioPath_ release];
  [developerDir_ release];
  [simulatorBundle_ release];
  [super dealloc];
}

// Reads data from the simulated app's output and writes it to stdout. This
// method blocks, so it should be called in a separate thread. The iOS
// Simulator takes a file path for the simulated app's stdout and stderr, but
// this path isn't always available (e.g. when the stdout is Xcode's build
// window). As a workaround, iossim creates a temp file to hold output, which
// this method reads and copies to stdout.
- (void)tailOutputForSession:(DTiPhoneSimulatorSession*)session {
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

  NSFileHandle* simio = [NSFileHandle fileHandleForReadingAtPath:stdioPath_];
  if (IsRunningWithXcode6OrLater()) {
#if defined(IOSSIM_USE_XCODE_6)
    // With iOS 8 simulators on Xcode 6, the app output is relative to the
    // simulator's data directory.
    NSString* versionString =
        [[[session sessionConfig] simulatedSystemRoot] sdkVersion];
    NSInteger majorVersion = [[[versionString componentsSeparatedByString:@"."]
        objectAtIndex:0] intValue];
    if (majorVersion >= 8) {
      NSString* dataPath = session.sessionConfig.device.dataPath;
      NSString* appOutput =
          [dataPath stringByAppendingPathComponent:stdioPath_];
      simio = [NSFileHandle fileHandleForReadingAtPath:appOutput];
    }
#endif  // IOSSIM_USE_XCODE_6
  }
  NSFileHandle* standardOutput = [NSFileHandle fileHandleWithStandardOutput];
  // Copy data to stdout/stderr while the app is running.
  while (appRunning_) {
    NSAutoreleasePool* innerPool = [[NSAutoreleasePool alloc] init];
    [standardOutput writeData:[simio readDataToEndOfFile]];
    [NSThread sleepForTimeInterval:kOutputPollIntervalSeconds];
    [innerPool drain];
  }

  // Once the app is no longer running, copy any data that was written during
  // the last sleep cycle.
  [standardOutput writeData:[simio readDataToEndOfFile]];

  [pool drain];
}

// Fetches a localized error string from the Simulator.
- (NSString *)localizedSimulatorErrorString:(NSString*)stringKey {
  // Lazy load of the simulator bundle.
  if (simulatorBundle_ == nil) {
    NSString* simulatorPath = [developerDir_
        stringByAppendingPathComponent:kSimulatorRelativePath];
    simulatorBundle_ = [NSBundle bundleWithPath:simulatorPath];
  }
  NSString *localizedStr =
      [simulatorBundle_ localizedStringForKey:stringKey
                                        value:nil
                                        table:nil];
  if ([localizedStr length])
    return localizedStr;
  // Failed to get a value, follow Cocoa conventions and use the key as the
  // string.
  return stringKey;
}

- (void)session:(DTiPhoneSimulatorSession*)session
       didStart:(BOOL)started
      withError:(NSError*)error {
  if (!started) {
    // If the test executes very quickly (<30ms), the SimulatorDelegate may not
    // get the initial session:started:withError: message indicating successful
    // startup of the simulated app. Instead the delegate will get a
    // session:started:withError: message after the timeout has elapsed. To
    // account for this case, check if the simulated app's stdio file was
    // ever created and if it exists dump it to stdout and return success.
    NSFileManager* fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:stdioPath_]) {
      appRunning_ = NO;
      [self tailOutputForSession:session];
      // Note that exiting in this state leaves a process running
      // (e.g. /.../iPhoneSimulator4.3.sdk/usr/libexec/installd -t 30) that will
      // prevent future simulator sessions from being started for 30 seconds
      // unless the iOS Simulator application is killed altogether.
      [self session:session didEndWithError:nil];

      // session:didEndWithError should not return (because it exits) so
      // the execution path should never get here.
      exit(kExitFailure);
    }

    LogError(@"Simulator failed to start: \"%@\" (%@:%ld)",
             [error localizedDescription],
             [error domain], static_cast<long int>([error code]));
    PrintSupportedDevices();
    exit(kExitAppFailedToStart);
  }

  // Start a thread to write contents of outputPath to stdout.
  appRunning_ = YES;
  outputThread_ =
      [[NSThread alloc] initWithTarget:self
                              selector:@selector(tailOutputForSession:)
                                object:session];
  [outputThread_ start];
}

- (void)session:(DTiPhoneSimulatorSession*)session
    didEndWithError:(NSError*)error {
  appRunning_ = NO;
  // Wait for the output thread to finish copying data to stdout.
  if (outputThread_) {
    while (![outputThread_ isFinished]) {
      [NSThread sleepForTimeInterval:kOutputPollIntervalSeconds];
    }
    [outputThread_ release];
    outputThread_ = nil;
  }

  if (error) {
    // There appears to be a race condition where sometimes the simulator
    // framework will end with an error, but the error is that the simulated
    // app cleanly shut down; try to trap this error and don't fail the
    // simulator run.
    NSString* localizedDescription = [error localizedDescription];
    NSString* ignorableErrorStr =
        [self localizedSimulatorErrorString:kSimulatorAppQuitErrorKey];
    if ([ignorableErrorStr isEqual:localizedDescription]) {
      LogWarning(@"Ignoring that Simulator ended with: \"%@\" (%@:%ld)",
                 localizedDescription, [error domain],
                 static_cast<long int>([error code]));
    } else {
      LogError(@"Simulator ended with error: \"%@\" (%@:%ld)",
               localizedDescription, [error domain],
               static_cast<long int>([error code]));
      exit(kExitFailure);
    }
  }

  // Try to determine if the simulated app crashed or quit with a non-zero
  // status code. iOS Simluator handles things a bit differently depending on
  // the version, so first determine the iOS version being used.
  BOOL badEntryFound = NO;
  NSString* versionString =
      [[[session sessionConfig] simulatedSystemRoot] sdkVersion];
  NSInteger majorVersion = [[[versionString componentsSeparatedByString:@"."]
      objectAtIndex:0] intValue];
  if (majorVersion <= 6) {
    // In iOS 6 and before, logging from the simulated apps went to the main
    // system logs, so use ASL to check if the simulated app exited abnormally
    // by looking for system log messages from launchd that refer to the
    // simulated app's PID. Limit query to messages in the last minute since
    // PIDs are cyclical.
    aslmsg query = asl_new(ASL_TYPE_QUERY);
    asl_set_query(query, ASL_KEY_SENDER, "launchd",
                  ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_SUBSTRING);
    char session_id[20];
    if (snprintf(session_id, 20, "%d", [session simulatedApplicationPID]) < 0) {
      LogError(@"Failed to get [session simulatedApplicationPID]");
      exit(kExitFailure);
    }
    asl_set_query(query, ASL_KEY_REF_PID, session_id, ASL_QUERY_OP_EQUAL);
    asl_set_query(query, ASL_KEY_TIME, "-1m", ASL_QUERY_OP_GREATER_EQUAL);

    // Log any messages found, and take note of any messages that may indicate
    // the app crashed or did not exit cleanly.
    aslresponse response = asl_search(NULL, query);
    aslmsg entry;
    while ((entry = aslresponse_next(response)) != NULL) {
      const char* message = asl_get(entry, ASL_KEY_MSG);
      LogWarning(@"Console message: %s", message);
      // Some messages are harmless, so don't trigger a failure for them.
      if (strstr(message, "The following job tried to hijack the service"))
        continue;
      badEntryFound = YES;
    }
  } else {
    // Otherwise, the iOS Simulator's system logging is sandboxed, so parse the
    // sandboxed system.log file for known errors.
    NSString* path;
    if (IsRunningWithXcode6OrLater()) {
#if defined(IOSSIM_USE_XCODE_6)
      NSString* dataPath = session.sessionConfig.device.dataPath;
      path =
          [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"];
#endif  // IOSSIM_USE_XCODE_6
    } else {
      NSString* relativePathToSystemLog =
          [NSString stringWithFormat:
              @"Library/Logs/iOS Simulator/%@/system.log", versionString];
      path = [simulatorHome_
          stringByAppendingPathComponent:relativePathToSystemLog];
    }
    NSFileManager* fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path]) {
      NSString* content =
          [NSString stringWithContentsOfFile:path
                                    encoding:NSUTF8StringEncoding
                                       error:NULL];
      NSArray* lines = [content componentsSeparatedByCharactersInSet:
          [NSCharacterSet newlineCharacterSet]];
      NSString* simulatedAppPID =
          [NSString stringWithFormat:@"%d", session.simulatedApplicationPID];
      NSArray* kErrorStrings = @[
        @"Service exited with abnormal code:",
        @"Service exited due to signal:",
      ];
      for (NSString* line in lines) {
        if ([line rangeOfString:simulatedAppPID].location != NSNotFound) {
          for (NSString* errorString in kErrorStrings) {
            if ([line rangeOfString:errorString].location != NSNotFound) {
              LogWarning(@"Console message: %@", line);
              badEntryFound = YES;
              break;
            }
          }
          if (badEntryFound) {
            break;
          }
        }
      }
      // Remove the log file so subsequent invocations of iossim won't be
      // looking at stale logs.
      remove([path fileSystemRepresentation]);
    } else {
        LogWarning(@"Unable to find system log at '%@'.", path);
    }
  }

  // If the query returned any nasty-looking results, iossim should exit with
  // non-zero status.
  if (badEntryFound) {
    LogError(@"Simulated app crashed or exited with non-zero status");
    exit(kExitAppCrashed);
  }
  exit(kExitSuccess);
}
@end

namespace {

// Finds the developer dir via xcode-select or the DEVELOPER_DIR environment
// variable.
NSString* FindDeveloperDir() {
  // Check the env first.
  NSDictionary* env = [[NSProcessInfo processInfo] environment];
  NSString* developerDir = [env objectForKey:@"DEVELOPER_DIR"];
  if ([developerDir length] > 0)
    return developerDir;

  // Go look for it via xcode-select.
  NSString* output = GetOutputFromTask(@"/usr/bin/xcode-select",
                                       @[ @"-print-path" ]);
  output = [output stringByTrimmingCharactersInSet:
      [NSCharacterSet whitespaceAndNewlineCharacterSet]];
  if ([output length] == 0)
    output = nil;
  return output;
}

// Loads the Simulator framework from the given developer dir.
NSBundle* LoadSimulatorFramework(NSString* developerDir) {
  // The Simulator framework depends on some of the other Xcode private
  // frameworks; manually load them first so everything can be linked up.
  NSString* dvtFoundationPath = [developerDir
      stringByAppendingPathComponent:kDVTFoundationRelativePath];
  NSBundle* dvtFoundationBundle =
      [NSBundle bundleWithPath:dvtFoundationPath];
  if (![dvtFoundationBundle load])
    return nil;

  NSString* devToolsFoundationPath = [developerDir
      stringByAppendingPathComponent:kDevToolsFoundationRelativePath];
  NSBundle* devToolsFoundationBundle =
      [NSBundle bundleWithPath:devToolsFoundationPath];
  if (![devToolsFoundationBundle load])
    return nil;

  // Prime DVTPlatform.
  NSError* error;
  Class DVTPlatformClass = FindClassByName(@"DVTPlatform");
  if (![DVTPlatformClass loadAllPlatformsReturningError:&error]) {
    LogError(@"Unable to loadAllPlatformsReturningError. Error: %@",
         [error localizedDescription]);
    return nil;
  }

  // The path within the developer dir of the private Simulator frameworks.
  NSString* simulatorFrameworkRelativePath;
  if (IsRunningWithXcode6OrLater()) {
    simulatorFrameworkRelativePath =
        @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework";
    NSString* const kCoreSimulatorRelativePath =
       @"Library/PrivateFrameworks/CoreSimulator.framework";
    NSString* coreSimulatorPath = [developerDir
        stringByAppendingPathComponent:kCoreSimulatorRelativePath];
    NSBundle* coreSimulatorBundle =
        [NSBundle bundleWithPath:coreSimulatorPath];
    if (![coreSimulatorBundle load])
      return nil;
  } else {
    simulatorFrameworkRelativePath =
      @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/"
      @"DVTiPhoneSimulatorRemoteClient.framework";
  }
  NSString* simBundlePath = [developerDir
      stringByAppendingPathComponent:simulatorFrameworkRelativePath];
  NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath];
  if (![simBundle load])
    return nil;
  return simBundle;
}

// Converts the given app path to an application spec, which requires an
// absolute path.
DTiPhoneSimulatorApplicationSpecifier* BuildAppSpec(NSString* appPath) {
  Class applicationSpecifierClass =
      FindClassByName(@"DTiPhoneSimulatorApplicationSpecifier");
  if (![appPath isAbsolutePath]) {
    NSString* cwd = [[NSFileManager defaultManager] currentDirectoryPath];
    appPath = [cwd stringByAppendingPathComponent:appPath];
  }
  appPath = [appPath stringByStandardizingPath];
  NSFileManager* fileManager = [NSFileManager defaultManager];
  if (![fileManager fileExistsAtPath:appPath]) {
    LogError(@"File not found: %@", appPath);
    exit(kExitInvalidArguments);
  }
  return [applicationSpecifierClass specifierWithApplicationPath:appPath];
}

// Returns the system root for the given SDK version. If sdkVersion is nil, the
// default system root is returned.  Will return nil if the sdkVersion is not
// valid.
DTiPhoneSimulatorSystemRoot* BuildSystemRoot(NSString* sdkVersion) {
  Class systemRootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot");
#if defined(IOSSIM_USE_XCODE_6)
  Class simRuntimeClass = FindClassByName(@"SimRuntime");
  NSArray* sorted =
      [[simRuntimeClass supportedRuntimes] sortedArrayUsingDescriptors:@[
        [NSSortDescriptor sortDescriptorWithKey:@"version" ascending:YES]
      ]];
  NSString* versionString = [[sorted lastObject] versionString];
  DTiPhoneSimulatorSystemRoot* systemRoot =
      [systemRootClass rootWithSDKVersion:versionString];
#else
  DTiPhoneSimulatorSystemRoot* systemRoot = [systemRootClass defaultRoot];
#endif
  if (sdkVersion)
    systemRoot = [systemRootClass rootWithSDKVersion:sdkVersion];

  return systemRoot;
}

// Builds a config object for starting the specified app.
DTiPhoneSimulatorSessionConfig* BuildSessionConfig(
    DTiPhoneSimulatorApplicationSpecifier* appSpec,
    DTiPhoneSimulatorSystemRoot* systemRoot,
    NSString* stdoutPath,
    NSString* stderrPath,
    NSArray* appArgs,
    NSDictionary* appEnv,
    NSNumber* deviceFamily,
    NSString* deviceName) {
  Class sessionConfigClass = FindClassByName(@"DTiPhoneSimulatorSessionConfig");
  DTiPhoneSimulatorSessionConfig* sessionConfig =
      [[[sessionConfigClass alloc] init] autorelease];
  sessionConfig.applicationToSimulateOnStart = appSpec;
  sessionConfig.simulatedSystemRoot = systemRoot;
  sessionConfig.localizedClientName = @"chromium";
  sessionConfig.simulatedApplicationStdErrPath = stderrPath;
  sessionConfig.simulatedApplicationStdOutPath = stdoutPath;
  sessionConfig.simulatedApplicationLaunchArgs = appArgs;
  sessionConfig.simulatedApplicationLaunchEnvironment = appEnv;
  sessionConfig.simulatedDeviceInfoName = deviceName;
  sessionConfig.simulatedDeviceFamily = deviceFamily;

  if (IsRunningWithXcode6OrLater()) {
#if defined(IOSSIM_USE_XCODE_6)
    Class simDeviceTypeClass = FindClassByName(@"SimDeviceType");
    id simDeviceType =
        [simDeviceTypeClass supportedDeviceTypesByAlias][deviceName];
    Class simRuntimeClass = FindClassByName(@"SimRuntime");
    NSString* identifier = systemRoot.runtime.identifier;
    id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier];

    // Attempt to use an existing device, but create one if a suitable match
    // can't be found. For example, if the simulator is running with a
    // non-default home directory (e.g. via iossim's -u command line arg) then
    // there won't be any devices so one will have to be created.
    Class simDeviceSetClass = FindClassByName(@"SimDeviceSet");
    id deviceSet =
        [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]];
    id simDevice = nil;
    for (id device in [deviceSet availableDevices]) {
      if ([device runtime] == simRuntime &&
          [device deviceType] == simDeviceType) {
        simDevice = device;
        break;
      }
    }
    if (!simDevice) {
      NSError* error = nil;
      // n.b. only the device name is necessary because the iOS Simulator menu
      // already splits devices by runtime version.
      NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName];
      simDevice = [deviceSet createDeviceWithType:simDeviceType
                                          runtime:simRuntime
                                             name:name
                                            error:&error];
      if (error) {
        LogError(@"Failed to create device: %@", error);
        exit(kExitInitializationFailure);
      }
    }
    sessionConfig.device = simDevice;
#endif  // IOSSIM_USE_XCODE_6
  }
  return sessionConfig;
}

// Builds a simulator session that will use the given delegate.
DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) {
  Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession");
  DTiPhoneSimulatorSession* session =
      [[[sessionClass alloc] init] autorelease];
  session.delegate = delegate;
  return session;
}

// Creates a temporary directory with a unique name based on the provided
// template. The template should not contain any path separators and be suffixed
// with X's, which will be substituted with a unique alphanumeric string (see
// 'man mkdtemp' for details). The directory will be created as a subdirectory
// of NSTemporaryDirectory(). For example, if dirNameTemplate is 'test-XXX',
// this method would return something like '/path/to/tempdir/test-3n2'.
//
// Returns the absolute path of the newly-created directory, or nill if unable
// to create a unique directory.
NSString* CreateTempDirectory(NSString* dirNameTemplate) {
  NSString* fullPathTemplate =
      [NSTemporaryDirectory() stringByAppendingPathComponent:dirNameTemplate];
  char* fullPath = mkdtemp(const_cast<char*>([fullPathTemplate UTF8String]));
  if (fullPath == NULL)
    return nil;

  return [NSString stringWithUTF8String:fullPath];
}

// Creates the necessary directory structure under the given user home directory
// path.
// Returns YES if successful, NO if unable to create the directories.
BOOL CreateHomeDirSubDirs(NSString* userHomePath) {
  NSFileManager* fileManager = [NSFileManager defaultManager];

  // Create user home and subdirectories.
  NSArray* subDirsToCreate = [NSArray arrayWithObjects:
                              @"Documents",
                              @"Library/Caches",
                              @"Library/Preferences",
                              nil];
  for (NSString* subDir in subDirsToCreate) {
    NSString* path = [userHomePath stringByAppendingPathComponent:subDir];
    NSError* error;
    if (![fileManager createDirectoryAtPath:path
                withIntermediateDirectories:YES
                                 attributes:nil
                                      error:&error]) {
      LogError(@"Unable to create directory: %@. Error: %@",
               path, [error localizedDescription]);
      return NO;
    }
  }

  return YES;
}

// Creates the necessary directory structure under the given user home directory
// path, then sets the path in the appropriate environment variable.
// Returns YES if successful, NO if unable to create or initialize the given
// directory.
BOOL InitializeSimulatorUserHome(NSString* userHomePath) {
  if (!CreateHomeDirSubDirs(userHomePath))
    return NO;

  // Update the environment to use the specified directory as the user home
  // directory.
  // Note: the third param of setenv specifies whether or not to overwrite the
  // variable's value if it has already been set.
  if ((setenv(kUserHomeEnvVariable, [userHomePath UTF8String], YES) == -1) ||
      (setenv(kHomeEnvVariable, [userHomePath UTF8String], YES) == -1)) {
    LogError(@"Unable to set environment variables for home directory.");
    return NO;
  }

  return YES;
}

// Performs a case-insensitive search to see if |stringToSearch| begins with
// |prefixToFind|. Returns true if a match is found.
BOOL CaseInsensitivePrefixSearch(NSString* stringToSearch,
                                 NSString* prefixToFind) {
  NSStringCompareOptions options = (NSAnchoredSearch | NSCaseInsensitiveSearch);
  NSRange range = [stringToSearch rangeOfString:prefixToFind
                                        options:options];
  return range.location != NSNotFound;
}

// Prints the usage information to stderr.
void PrintUsage() {
  fprintf(stderr, "Usage: iossim [-d device] [-s sdkVersion] [-u homeDir] "
      "[-e envKey=value]* [-t startupTimeout] <appPath> [<appArgs>]\n"
      "  where <appPath> is the path to the .app directory and appArgs are any"
      " arguments to send the simulated app.\n"
      "\n"
      "Options:\n"
      "  -d  Specifies the device (must be one of the values from the iOS"
      " Simulator's Hardware -> Device menu. Defaults to 'iPhone'.\n"
      "  -s  Specifies the SDK version to use (e.g '4.3')."
      " Will use system default if not specified.\n"
      "  -u  Specifies a user home directory for the simulator."
      " Will create a new directory if not specified.\n"
      "  -e  Specifies an environment key=value pair that will be"
      " set in the simulated application's environment.\n"
      "  -t  Specifies the session startup timeout (in seconds)."
      " Defaults to %d.\n"
      "  -l  List supported devices and iOS versions.\n",
      static_cast<int>(kDefaultSessionStartTimeoutSeconds));
}
}  // namespace

void EnsureSupportForCurrentXcodeVersion() {
  if (IsRunningWithXcode6OrLater()) {
#if !IOSSIM_USE_XCODE_6
    LogError(@"Running on Xcode 6, but Xcode 6 support was not compiled in.");
    exit(kExitUnsupportedXcodeVersion);
#endif  // IOSSIM_USE_XCODE_6
  }
}

int main(int argc, char* const argv[]) {
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

  EnsureSupportForCurrentXcodeVersion();

  // basename() may modify the passed in string and it returns a pointer to an
  // internal buffer. Give it a copy to modify, and copy what it returns.
  char* worker = strdup(argv[0]);
  char* toolName = basename(worker);
  if (toolName != NULL) {
    toolName = strdup(toolName);
    if (toolName != NULL)
      gToolName = toolName;
  }
  if (worker != NULL)
    free(worker);

  NSString* appPath = nil;
  NSString* appName = nil;
  NSString* sdkVersion = nil;
  NSString* deviceName =
      IsRunningWithXcode6OrLater() ? @"iPhone 5s" : @"iPhone";
  NSString* simHomePath = nil;
  NSMutableArray* appArgs = [NSMutableArray array];
  NSMutableDictionary* appEnv = [NSMutableDictionary dictionary];
  NSTimeInterval sessionStartTimeout = kDefaultSessionStartTimeoutSeconds;

  NSString* developerDir = FindDeveloperDir();
  if (!developerDir) {
    LogError(@"Unable to find developer directory.");
    exit(kExitInitializationFailure);
  }

  NSBundle* simulatorFramework = LoadSimulatorFramework(developerDir);
  if (!simulatorFramework) {
    LogError(@"Failed to load the Simulator Framework.");
    exit(kExitInitializationFailure);
  }

  // Parse the optional arguments
  int c;
  while ((c = getopt(argc, argv, "hs:d:u:e:t:l")) != -1) {
    switch (c) {
      case 's':
        sdkVersion = [NSString stringWithUTF8String:optarg];
        break;
      case 'd':
        deviceName = [NSString stringWithUTF8String:optarg];
        break;
      case 'u':
        simHomePath = [[NSFileManager defaultManager]
            stringWithFileSystemRepresentation:optarg length:strlen(optarg)];
        break;
      case 'e': {
        NSString* envLine = [NSString stringWithUTF8String:optarg];
        NSRange range = [envLine rangeOfString:@"="];
        if (range.location == NSNotFound) {
          LogError(@"Invalid key=value argument for -e.");
          PrintUsage();
          exit(kExitInvalidArguments);
        }
        NSString* key = [envLine substringToIndex:range.location];
        NSString* value = [envLine substringFromIndex:(range.location + 1)];
        [appEnv setObject:value forKey:key];
      }
        break;
      case 't': {
        int timeout = atoi(optarg);
        if (timeout > 0) {
          sessionStartTimeout = static_cast<NSTimeInterval>(timeout);
        } else {
          LogError(@"Invalid startup timeout (%s).", optarg);
          PrintUsage();
          exit(kExitInvalidArguments);
        }
      }
        break;
      case 'l':
        PrintSupportedDevices();
        exit(kExitSuccess);
        break;
      case 'h':
        PrintUsage();
        exit(kExitSuccess);
      default:
        PrintUsage();
        exit(kExitInvalidArguments);
    }
  }

  // There should be at least one arg left, specifying the app path. Any
  // additional args are passed as arguments to the app.
  if (optind < argc) {
    appPath = [[NSFileManager defaultManager]
        stringWithFileSystemRepresentation:argv[optind]
                                    length:strlen(argv[optind])];
    appName = [appPath lastPathComponent];
    while (++optind < argc) {
      [appArgs addObject:[NSString stringWithUTF8String:argv[optind]]];
    }
  } else {
    LogError(@"Unable to parse command line arguments.");
    PrintUsage();
    exit(kExitInvalidArguments);
  }

  // Make sure the app path provided is legit.
  DTiPhoneSimulatorApplicationSpecifier* appSpec = BuildAppSpec(appPath);
  if (!appSpec) {
    LogError(@"Invalid app path: %@", appPath);
    exit(kExitInitializationFailure);
  }

  // Make sure the SDK path provided is legit (or nil).
  DTiPhoneSimulatorSystemRoot* systemRoot = BuildSystemRoot(sdkVersion);
  if (!systemRoot) {
    LogError(@"Invalid SDK version: %@", sdkVersion);
    PrintSupportedDevices();
    exit(kExitInitializationFailure);
  }

  // Get the paths for stdout and stderr so the simulated app's output will show
  // up in the caller's stdout/stderr.
  NSString* outputDir = CreateTempDirectory(@"iossim-XXXXXX");
  NSString* stdioPath = [outputDir stringByAppendingPathComponent:@"stdio.txt"];

  // Determine the deviceFamily based on the deviceName
  NSNumber* deviceFamily = nil;
  if (IsRunningWithXcode6OrLater()) {
#if defined(IOSSIM_USE_XCODE_6)
    Class simDeviceTypeClass = FindClassByName(@"SimDeviceType");
    if ([simDeviceTypeClass supportedDeviceTypesByAlias][deviceName] == nil) {
      LogError(@"Invalid device name: %@.", deviceName);
      PrintSupportedDevices();
      exit(kExitInvalidArguments);
    }
#endif  // IOSSIM_USE_XCODE_6
  } else {
    if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) {
      deviceFamily = [NSNumber numberWithInt:kIPhoneFamily];
    } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) {
      deviceFamily = [NSNumber numberWithInt:kIPadFamily];
    }
    else {
      LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'",
               deviceName);
      exit(kExitInvalidArguments);
    }
  }

  // Set up the user home directory for the simulator only if a non-default
  // value was specified.
  if (simHomePath) {
    if (!InitializeSimulatorUserHome(simHomePath)) {
      LogError(@"Unable to initialize home directory for simulator: %@",
               simHomePath);
      exit(kExitInitializationFailure);
    }
  } else {
    simHomePath = NSHomeDirectory();
  }

  // Create the config and simulator session.
  DTiPhoneSimulatorSessionConfig* config = BuildSessionConfig(appSpec,
                                                              systemRoot,
                                                              stdioPath,
                                                              stdioPath,
                                                              appArgs,
                                                              appEnv,
                                                              deviceFamily,
                                                              deviceName);
  SimulatorDelegate* delegate =
      [[[SimulatorDelegate alloc] initWithStdioPath:stdioPath
                                       developerDir:developerDir
                                      simulatorHome:simHomePath] autorelease];
  DTiPhoneSimulatorSession* session = BuildSession(delegate);

  // Start the simulator session.
  NSError* error;
  BOOL started = [session requestStartWithConfig:config
                                         timeout:sessionStartTimeout
                                           error:&error];

  // Spin the runtime indefinitely. When the delegate gets the message that the
  // app has quit it will exit this program.
  if (started) {
    [[NSRunLoop mainRunLoop] run];
  } else {
    LogError(@"Simulator failed request to start:  \"%@\" (%@:%ld)",
             [error localizedDescription],
             [error domain], static_cast<long int>([error code]));
  }

  // Note that this code is only executed if the simulator fails to start
  // because once the main run loop is started, only the delegate calling
  // exit() will end the program.
  [pool drain];
  return kExitFailure;
}
