// 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.

@class DVTStackBacktrace;
#import "DVTFoundation.h"

@protocol SimBridge;
@class DVTSimulatorApplication;
@class SimDeviceSet;
@class SimDeviceType;
@class SimProfilesPathMonitor;
@class SimRuntime;
@class SimServiceConnectionManager;
#import "CoreSimulator.h"

@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";

// 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;

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];
}

// Prints supported devices and SDKs.
void PrintSupportedDevices() {
  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]);
  }
}
}  // 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_];
  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];
  }
  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;

  // The iOS Simulator's system logging is sandboxed, so parse the sandboxed
  // system.log file for known errors.
  NSString* path;
  NSString* dataPath = session.sessionConfig.device.dataPath;
  path =
      [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"];
  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;
  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;
  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");
  Class simRuntimeClass = FindClassByName(@"SimRuntime");
  NSArray* sorted =
      [[simRuntimeClass supportedRuntimes] sortedArrayUsingDescriptors:@[
        [NSSortDescriptor sortDescriptorWithKey:@"version" ascending:YES]
      ]];
  NSString* versionString = [[sorted lastObject] versionString];
  DTiPhoneSimulatorSystemRoot* systemRoot =
      [systemRootClass rootWithSDKVersion:versionString];
  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;

  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;
  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;
}

// 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

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

  // 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 = @"iPhone 5s";
  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;
  Class simDeviceTypeClass = FindClassByName(@"SimDeviceType");
  if ([simDeviceTypeClass supportedDeviceTypesByAlias][deviceName] == nil) {
    LogError(@"Invalid device name: %@.", deviceName);
    PrintSupportedDevices();
    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;
}
