//TODO: don't copy/mount DeveloperDiskImage.dmg if it's already done - Xcode checks this somehow

#import <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <signal.h>
#include <getopt.h>
#include <pwd.h>
#include <dlfcn.h>
#include <time.h>

#include <netinet/in.h>
#include <netinet/tcp.h>

#include "MobileDevice.h"
#import "errors.h"
#import "device_db.h"

#define PREP_CMDS_PATH @"/tmp/%@/fruitstrap-lldb-prep-cmds-"
#define LLDB_SHELL @"PATH=/usr/bin /usr/bin/lldb -s %@"
/*
 * Startup script passed to lldb.
 * To see how xcode interacts with lldb, put this into .lldbinit:
 * log enable -v -f /Users/vargaz/lldb.log lldb all
 * log enable -v -f /Users/vargaz/gdb-remote.log gdb-remote all
 */
#define LLDB_PREP_CMDS CFSTR("\
    platform select remote-'{platform}' --sysroot '{symbols_path}'\n\
    target create \"{disk_app}\"\n\
    script fruitstrap_device_app=\"{device_app}\"\n\
    script fruitstrap_connect_url=\"connect://127.0.0.1:{device_port}\"\n\
    script fruitstrap_output_path=\"{output_path}\"\n\
    script fruitstrap_error_path=\"{error_path}\"\n\
    target modules search-paths add {modules_search_paths_pairs}\n\
    command script import \"{python_file_path}\"\n\
    command script add -f {python_command}.connect_command connect\n\
    command script add -s asynchronous -f {python_command}.run_command run\n\
    command script add -s asynchronous -f {python_command}.autoexit_command autoexit\n\
    command script add -s asynchronous -f {python_command}.safequit_command safequit\n\
    connect\n\
")

const char* lldb_prep_no_cmds = "";

const char* lldb_prep_interactive_cmds = "\
    run\n\
";

const char* lldb_prep_noninteractive_justlaunch_cmds = "\
    run\n\
    safequit\n\
";

const char* lldb_prep_noninteractive_cmds = "\
    run\n\
    autoexit\n\
";

NSMutableString * custom_commands = nil;

/*
 * Some things do not seem to work when using the normal commands like process connect/launch, so we invoke them
 * through the python interface. Also, Launch () doesn't seem to work when ran from init_module (), so we add
 * a command which can be used by the user to run it.
 */
NSString* LLDB_FRUITSTRAP_MODULE = @
    #include "lldb.py.h"
;

const char* output_path = NULL;
const char* error_path = NULL;

typedef struct am_device * AMDeviceRef;
mach_error_t AMDeviceSecureStartService(AMDeviceRef device, CFStringRef service_name, unsigned int *unknown, ServiceConnRef * handle);
mach_error_t AMDeviceCreateHouseArrestService(AMDeviceRef device, CFStringRef identifier, CFDictionaryRef options, AFCConnectionRef * handle);
CFSocketNativeHandle  AMDServiceConnectionGetSocket(ServiceConnRef con);
void AMDServiceConnectionInvalidate(ServiceConnRef con);

bool AMDeviceIsAtLeastVersionOnPlatform(AMDeviceRef device, CFDictionaryRef vers);
int AMDeviceSecureTransferPath(int zero, AMDeviceRef device, CFURLRef url, CFDictionaryRef options, void *callback, int cbarg);
int AMDeviceSecureInstallApplication(int zero, AMDeviceRef device, CFURLRef url, CFDictionaryRef options, void *callback, int cbarg);
int AMDeviceSecureInstallApplicationBundle(AMDeviceRef device, CFURLRef url, CFDictionaryRef options, void *callback, int cbarg);
int AMDeviceMountImage(AMDeviceRef device, CFStringRef image, CFDictionaryRef options, void *callback, int cbarg);
mach_error_t AMDeviceLookupApplications(AMDeviceRef device, CFDictionaryRef options, CFDictionaryRef *result);
int AMDeviceGetInterfaceType(AMDeviceRef device);
AMDeviceRef AMDeviceCopyPairedCompanion(AMDeviceRef device);

int AMDServiceConnectionSend(ServiceConnRef con, const void * data, size_t size);
int AMDServiceConnectionReceive(ServiceConnRef con, void * data, size_t size);
uint64_t AMDServiceConnectionReceiveMessage(ServiceConnRef con, CFPropertyListRef message, CFPropertyListFormat *format);
uint64_t AMDServiceConnectionSendMessage(ServiceConnRef con, CFPropertyListRef message, CFPropertyListFormat format);
CFArrayRef AMDeviceCopyProvisioningProfiles(AMDeviceRef device);
int AMDeviceInstallProvisioningProfile(AMDeviceRef device, void *profile);
int AMDeviceRemoveProvisioningProfile(AMDeviceRef device, CFStringRef uuid);
CFStringRef MISProfileGetValue(void *profile, CFStringRef key);
CFDictionaryRef MISProfileCopyPayload(void *profile);
void *MISProfileCreateWithData(int zero, CFDataRef data);
int MISProfileWriteToFile(void *profile, CFStringRef dest_path);

bool found_device = false, debug = false, verbose = false, unbuffered = false, nostart = false, debugserver_only = false, detect_only = false, install = true, uninstall = false, no_wifi = false;
bool faster_path_search = false;
bool command_only = false;
char *command = NULL;
char const*target_filename = NULL;
char const*upload_pathname = NULL;
char *bundle_id = NULL;
NSMutableArray *keys = NULL;
bool interactive = true;
bool justlaunch = false;
bool file_system = false;
bool non_recursively = false;
char *app_path = NULL;
char *app_deltas = NULL;
char *device_id = NULL;
char *args = NULL;
char *envs = NULL;
char *list_root = NULL;
const char * custom_script_path = NULL;
char *symbols_download_directory = NULL;
char *profile_uuid = NULL;
char *profile_path = NULL;
int _timeout = 0;
int _detectDeadlockTimeout = 0;
bool _json_output = false;
NSMutableArray *_file_meta_info = nil;
int port = 0;    // 0 means "dynamically assigned"
ServiceConnRef dbgServiceConnection = NULL;
pid_t parent = 0;
// PID of child process running lldb
pid_t child = 0;
// Signal sent from child to parent process when LLDB finishes.
const int SIGLLDB = SIGUSR1;
NSString* tmpUUID;
struct am_device_notification *notify;
CFRunLoopSourceRef lldb_socket_runloop;
CFRunLoopSourceRef server_socket_runloop;
CFRunLoopSourceRef fdvendor_runloop;

uint32_t symbols_file_paths_command = 0x30303030;
uint32_t symbols_download_file_command = 0x01000000;
CFStringRef symbols_service_name = CFSTR("com.apple.dt.fetchsymbols");
const int symbols_logging_interval_ms = 250;

const size_t sizeof_uint32_t = sizeof(uint32_t);

// Error codes we report on different failures, so scripts can distinguish between user app exit
// codes and our exit codes. For non app errors we use codes in reserved 128-255 range.
const int exitcode_timeout = 252;
const int exitcode_error = 253;
const int exitcode_app_crash = 254;

// Checks for MobileDevice.framework errors, tries to print them and exits.
#define check_error(call)                                                       \
    do {                                                                        \
        unsigned int err = (unsigned int)call;                                  \
        if (err != 0)                                                           \
        {                                                                       \
            const char* msg = get_error_message(err);                           \
            NSString *description = msg ? [NSString stringWithUTF8String:msg] : @"unknown."; \
            NSLogJSON(@{@"Event": @"Error", @"Code": @(err), @"Status": description}); \
            on_error(@"Error 0x%x: %@ " #call, err, description);               \
        }                                                                       \
    } while (false);

// Checks for MobileDevice.framework errors and tries to print them.
#define log_error(call)                                                       \
    do {                                                                        \
        unsigned int err = (unsigned int)call;                                  \
        if (err != 0)                                                           \
        {                                                                       \
            const char* msg = get_error_message(err);                           \
            NSString *description = msg ? [NSString stringWithUTF8String:msg] : @"unknown."; \
            NSLogJSON(@{@"Event": @"Error", @"Code": @(err), @"Status": description}); \
            log_on_error(@"Error 0x%x: %@ " #call, err, description);               \
        }                                                                       \
    } while (false);



void disable_ssl(ServiceConnRef con)
{
    // MobileDevice links with SSL, so function will be available;
    typedef void (*SSL_free_t)(void*);
    static SSL_free_t SSL_free = NULL;
    if (SSL_free == NULL)
    {
        SSL_free = (SSL_free_t)dlsym(RTLD_DEFAULT, "SSL_free");
    }

    SSL_free(con->sslContext);
    con->sslContext = NULL;
}

void log_on_error(NSString* format, ...)
{
    va_list valist;
    va_start(valist, format);
    NSString* str = [[[NSString alloc] initWithFormat:format arguments:valist] autorelease];
    va_end(valist);

    if (!_json_output) {
        NSLog(@"[ !! ] %@", str);
    }
}


void on_error(NSString* format, ...)
{
    va_list valist;
    va_start(valist, format);
    NSString* str = [[[NSString alloc] initWithFormat:format arguments:valist] autorelease];
    va_end(valist);

    if (!_json_output) {
        NSLog(@"[ !! ] %@", str);
    }

    exit(exitcode_error);
}

// Print error message getting last errno and exit
void on_sys_error(NSString* format, ...) {
    const char* errstr = strerror(errno);

    va_list valist;
    va_start(valist, format);
    NSString* str = [[[NSString alloc] initWithFormat:format arguments:valist] autorelease];
    va_end(valist);

    on_error(@"%@ : %@", str, [NSString stringWithUTF8String:errstr]);
}

void __NSLogOut(NSString* format, va_list valist) {
    NSString* str = [[[NSString alloc] initWithFormat:format arguments:valist] autorelease];
    [[str stringByAppendingString:@"\n"] writeToFile:@"/dev/stdout" atomically:NO encoding:NSUTF8StringEncoding error:nil];
}

void NSLogOut(NSString* format, ...) {
    if (!_json_output) {
        va_list valist;
        va_start(valist, format);
        __NSLogOut(format, valist);
        va_end(valist);
    }
}

void NSLogVerbose(NSString* format, ...) {
    if (verbose && !_json_output) {
        va_list valist;
        va_start(valist, format);
        __NSLogOut(format, valist);
        va_end(valist);
    }
}

void NSLogJSON(NSDictionary* jsonDict) {
    if (_json_output) {
        NSError *error;
        NSData *data = [NSJSONSerialization dataWithJSONObject:jsonDict
                                                           options:NSJSONWritingPrettyPrinted
                                                             error:&error];
        if (data) {
            NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            [jsonString writeToFile:@"/dev/stdout" atomically:NO encoding:NSUTF8StringEncoding error:nil];
            [jsonString release];
        } else {
            [@"{\"JSONError\": \"JSON error\"}" writeToFile:@"/dev/stdout" atomically:NO encoding:NSUTF8StringEncoding error:nil];
        }
    }
}

uint64_t get_current_time_in_milliseconds() {
    return clock_gettime_nsec_np(CLOCK_REALTIME) / (1000 * 1000);
}

BOOL mkdirp(NSString* path) {
    NSError* error = nil;
    BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:path
                                             withIntermediateDirectories:YES
                                                              attributes:nil
                                                                   error:&error];
    return success;
}

Boolean path_exists(CFTypeRef path) {
    if (CFGetTypeID(path) == CFStringGetTypeID()) {
        CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, true);
        Boolean result = CFURLResourceIsReachable(url, NULL);
        CFRelease(url);
        return result;
    } else if (CFGetTypeID(path) == CFURLGetTypeID()) {
        return CFURLResourceIsReachable(path, NULL);
    } else {
        return false;
    }
}

CFStringRef copy_find_path(CFStringRef rootPath, CFStringRef namePattern) {
    FILE *fpipe = NULL;
    CFStringRef cf_command;

    if( !path_exists(rootPath) )
        return NULL;

    if (faster_path_search) {
        CFIndex maxdepth = 1;
        CFArrayRef findPathSlash = CFStringCreateArrayWithFindResults(NULL, namePattern, CFSTR("/"), CFRangeMake(0, CFStringGetLength(namePattern)), 0);
        if (findPathSlash != NULL) {
            maxdepth = CFArrayGetCount(findPathSlash) + 1;
            CFRelease(findPathSlash);
        }

        cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find '%@' -path '%@/%@' -maxdepth %ld 2>/dev/null | sort | tail -n 1"), rootPath, rootPath, namePattern, maxdepth);
    }
    else {
        if (CFStringFind(namePattern, CFSTR("*"), 0).location == kCFNotFound) {
            //No wildcards. Let's speed up the search
            CFStringRef path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), rootPath, namePattern);
            
            if( path_exists(path) )
                return path;
            
            CFRelease(path);
            return NULL;
        }
        
        if (CFStringFind(namePattern, CFSTR("/"), 0).location == kCFNotFound) {
            cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find '%@' -name '%@' -maxdepth 1 2>/dev/null | sort | tail -n 1"), rootPath, namePattern);
        } else {
            cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find '%@' -path '%@/%@' 2>/dev/null | sort | tail -n 1"), rootPath, rootPath, namePattern);
        }
    }

    char command[1024] = { '\0' };
    CFStringGetCString(cf_command, command, sizeof(command), kCFStringEncodingUTF8);
    CFRelease(cf_command);

    if (!(fpipe = (FILE *)popen(command, "r")))
        on_sys_error(@"Error encountered while opening pipe");

    char buffer[256] = { '\0' };

    fgets(buffer, sizeof(buffer), fpipe);
    pclose(fpipe);

    strtok(buffer, "\n");
    
    CFStringRef path = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
        
    if( CFStringGetLength(path) > 0 && path_exists(path) )
        return path;

    CFRelease(path);
    return NULL;
}

CFStringRef copy_xcode_dev_path(void) {
    static char xcode_dev_path[256] = { '\0' };
    if (strlen(xcode_dev_path) == 0) {
        const char* env_dev_path = getenv("DEVELOPER_DIR");
        
        if (env_dev_path && strlen(env_dev_path) > 0) {
            strcpy(xcode_dev_path, env_dev_path);
            // DEVELOPER_DIR should refer to Xcode.app/Contents/Developer, but
            // xcode-select and friends have an extension to fix the path, if it points to Xcode.app/.
            static char dev_subdir[256] = { '\0' };
            strcat(strcat(dev_subdir, env_dev_path), "/Contents/Developer");
            struct stat sb;
            if (stat(dev_subdir, &sb) == 0)
            {
                strcpy(xcode_dev_path, dev_subdir);
            }
        } else {
            FILE *fpipe = NULL;
            char *command = "xcode-select -print-path";

            if (!(fpipe = (FILE *)popen(command, "r")))
                on_sys_error(@"Error encountered while opening pipe");

            char buffer[256] = { '\0' };

            fgets(buffer, sizeof(buffer), fpipe);
            pclose(fpipe);

            strtok(buffer, "\n");
            strcpy(xcode_dev_path, buffer);
        }
        NSLogVerbose(@"Found Xcode developer dir %s", xcode_dev_path);
    }
    return CFStringCreateWithCString(NULL, xcode_dev_path, kCFStringEncodingUTF8);
}

const char *get_home(void) {
    const char* home = getenv("HOME");
    if (!home) {
        struct passwd *pwd = getpwuid(getuid());
        home = pwd->pw_dir;
    }
    return home;
}

CFStringRef copy_xcode_path_for_impl(CFStringRef rootPath, CFStringRef subPath, CFStringRef search) {
    CFStringRef searchPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), rootPath, subPath );
    CFStringRef res = copy_find_path(searchPath, search);
    CFRelease(searchPath);
    return res;
}

CFStringRef copy_xcode_path_for(CFStringRef subPath, CFStringRef search) {
    CFStringRef xcodeDevPath = copy_xcode_dev_path();
    CFStringRef defaultXcodeDevPath = CFSTR("/Applications/Xcode.app/Contents/Developer");
    CFStringRef path = NULL;
    const char* home = get_home();
    
    // Try using xcode-select --print-path
    path = copy_xcode_path_for_impl(xcodeDevPath, subPath, search);
    
    // If not look in the default xcode location (xcode-select is sometimes wrong)
    if (path == NULL && CFStringCompare(xcodeDevPath, defaultXcodeDevPath, 0) != kCFCompareEqualTo )
        path = copy_xcode_path_for_impl(defaultXcodeDevPath, subPath, search);

    // If not look in the users home directory, Xcode can store device support stuff there
    if (path == NULL) {
        CFRelease(xcodeDevPath);
        xcodeDevPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s/Library/Developer/Xcode"), home );
        path = copy_xcode_path_for_impl(xcodeDevPath, subPath, search);
    }

    CFRelease(xcodeDevPath);
    
    return path;
}

device_desc get_device_desc(CFStringRef model) {
    if (model != NULL) {
        size_t sz = sizeof(device_db) / sizeof(device_desc);
        for (size_t i = 0; i < sz; i ++) {
            if (CFStringCompare(model, device_db[i].model, kCFCompareNonliteral | kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
                return device_db[i];
            }
        }
    }
    
    device_desc res = device_db[UNKNOWN_DEVICE_IDX];
    
    res.model = model;
    res.name = model;
    
    return res;
}

CFStringRef get_device_full_name(const AMDeviceRef device) {
    CFStringRef full_name = NULL,
                device_udid = AMDeviceCopyDeviceIdentifier(device),
                device_name = NULL,
                model_name = NULL,
                sdk_name = NULL,
                arch_name = NULL,
                product_version = NULL,
                build_version = NULL;

    AMDeviceConnect(device);

    device_name = AMDeviceCopyValue(device, 0, CFSTR("DeviceName"));

    // Please ensure that device is connected or the name will be unknown
    CFStringRef model = AMDeviceCopyValue(device, 0, CFSTR("HardwareModel"));
    device_desc dev;
    if (model != NULL) {
        dev = get_device_desc(model);
    } else {
        dev= device_db[UNKNOWN_DEVICE_IDX];
        model = dev.model;
    }
    model_name = dev.name;
    sdk_name = dev.sdk;
    arch_name = dev.arch;
    product_version = AMDeviceCopyValue(device, 0, CFSTR("ProductVersion"));
    build_version = AMDeviceCopyValue(device, 0, CFSTR("BuildVersion"));

    NSLogVerbose(@"Hardware Model: %@", model);
    NSLogVerbose(@"Device Name: %@", device_name);
    NSLogVerbose(@"Model Name: %@", model_name);
    NSLogVerbose(@"SDK Name: %@", sdk_name);
    NSLogVerbose(@"Architecture Name: %@", arch_name);
    NSLogVerbose(@"Product Version: %@", product_version);
    NSLogVerbose(@"Build Version: %@", build_version);
    if (build_version == 0)
        build_version = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8);

    if (device_name != NULL) {
        full_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@, %@, %@, %@, %@, %@) a.k.a. '%@'"), device_udid, model, model_name, sdk_name, arch_name, product_version, build_version, device_name);
    } else {
        full_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@, %@, %@, %@, %@, %@)"), device_udid, model, model_name, sdk_name, arch_name, product_version, build_version);
    }

    AMDeviceDisconnect(device);

    if(device_udid != NULL)
        CFRelease(device_udid);
    if(device_name != NULL)
        CFRelease(device_name);
    if(model != NULL)
        CFRelease(model);
    if(model_name != NULL && model_name != model)
        CFRelease(model_name);
    if(product_version)
        CFRelease(product_version);
    if(build_version)
        CFRelease(build_version);

    return CFAutorelease(full_name);
}

NSDictionary* get_device_json_dict(const AMDeviceRef device) {
    NSMutableDictionary *json_dict = [NSMutableDictionary new];
    AMDeviceConnect(device);
    
    CFStringRef device_udid = AMDeviceCopyDeviceIdentifier(device);
    if (device_udid) {
        [json_dict setValue:(__bridge NSString *)device_udid forKey:@"DeviceIdentifier"];
        CFRelease(device_udid);
    }
    
    CFStringRef device_hardware_model = AMDeviceCopyValue(device, 0, CFSTR("HardwareModel"));
    if (device_hardware_model) {
        [json_dict setValue:(NSString*)device_hardware_model forKey:@"HardwareModel"];
        size_t device_db_length = sizeof(device_db) / sizeof(device_desc);
        for (size_t i = 0; i < device_db_length; i ++) {
            if (CFStringCompare(device_hardware_model, device_db[i].model, kCFCompareNonliteral | kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
                device_desc dev = device_db[i];
                [json_dict setValue:(__bridge NSString *)dev.name forKey:@"modelName"];
                [json_dict setValue:(__bridge NSString *)dev.sdk forKey:@"modelSDK"];
                [json_dict setValue:(__bridge NSString *)dev.arch forKey:@"modelArch"];
                break;
            }
        }
        CFRelease(device_hardware_model);
    }
    
    for (NSString *deviceValue in @[@"DeviceName",
                                    @"BuildVersion",
                                    @"DeviceClass",
                                    @"ProductType",
                                    @"ProductVersion"]) {
        CFStringRef cf_value = AMDeviceCopyValue(device, 0, (__bridge CFStringRef)deviceValue);
        if (cf_value) {
            [json_dict setValue:(__bridge NSString *)cf_value forKey:deviceValue];
            CFRelease(cf_value);
        }
    }
    
    AMDeviceDisconnect(device);

    return CFAutorelease(json_dict);
}

int get_companion_interface_type(AMDeviceRef device)
{
    assert(AMDeviceGetInterfaceType(device) == 3);
    AMDeviceRef companion = AMDeviceCopyPairedCompanion(device);
    int type = AMDeviceGetInterfaceType(companion);
    AMDeviceRelease(companion);
    return type;
}

CFStringRef get_device_interface_name(const AMDeviceRef device) {
    // AMDeviceGetInterfaceType(device) 0=Unknown, 1 = Direct/USB, 2 = Indirect/WIFI, 3 = Companion proxy
    switch(AMDeviceGetInterfaceType(device)) {
        case 1:
            return CFSTR("USB");
        case 2:
            return CFSTR("WIFI");
        case 3:
        {
            if (get_companion_interface_type(device) == 1)
            {
                return CFSTR("USB Companion proxy");
            }
            else
            {
                return CFSTR("WIFI Companion proxy");
            }
        }
        default:
            return CFSTR("Unknown Connection");
    }
}

CFMutableArrayRef copy_device_product_version_parts(AMDeviceRef device) {
    CFStringRef version = AMDeviceCopyValue(device, 0, CFSTR("ProductVersion"));
    CFArrayRef parts = CFStringCreateArrayBySeparatingStrings(NULL, version, CFSTR("."));
    CFMutableArrayRef result = CFArrayCreateMutableCopy(NULL, CFArrayGetCount(parts), parts);
    CFRelease(version);
    CFRelease(parts);
    return result;
}

CFStringRef copy_device_support_path(AMDeviceRef device, CFStringRef suffix) {
    time_t startTime, endTime;
    time( &startTime );
    
    CFStringRef version = NULL;
    CFStringRef build = AMDeviceCopyValue(device, 0, CFSTR("BuildVersion"));
    CFStringRef deviceClass = AMDeviceCopyValue(device, 0, CFSTR("DeviceClass"));
    CFStringRef deviceModel = AMDeviceCopyValue(device, 0, CFSTR("HardwareModel"));
    CFStringRef productType = AMDeviceCopyValue(device, 0, CFSTR("ProductType"));
    CFStringRef deviceArch = NULL;
    CFStringRef path = NULL;

    device_desc dev;
    if (deviceModel != NULL) {
        dev = get_device_desc(deviceModel);
        deviceArch = dev.arch;
    }

    CFMutableArrayRef version_parts = copy_device_product_version_parts(device);

    NSLogVerbose(@"Device Class: %@", deviceClass);
    NSLogVerbose(@"build: %@", build);

    CFStringRef deviceClassPath[2];
    
    if (CFStringCompare(CFSTR("AppleTV"), deviceClass, 0) == kCFCompareEqualTo) {
      deviceClassPath[0] = CFSTR("Platforms/AppleTVOS.platform/DeviceSupport");
      deviceClassPath[1] = CFSTR("tvOS DeviceSupport");
    }
    else if (CFStringCompare(CFSTR("Watch"), deviceClass, 0) == kCFCompareEqualTo) {
      deviceClassPath[0] = CFSTR("Platforms/WatchOS.platform/DeviceSupport");
      deviceClassPath[1] = CFSTR("watchOS DeviceSupport");
    }
    else {
      deviceClassPath[0] = CFSTR("Platforms/iPhoneOS.platform/DeviceSupport");
      deviceClassPath[1] = CFSTR("iOS DeviceSupport");
    }
    while (CFArrayGetCount(version_parts) > 0) {
        version = CFStringCreateByCombiningStrings(NULL, version_parts, CFSTR("."));
        NSLogVerbose(@"version: %@", version);
        
        for( int i = 0; i < 2; ++i ) {
            if (path == NULL) {
                CFStringRef search = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@) %@/%@"), version, build, deviceArch, suffix);
                path = copy_xcode_path_for(deviceClassPath[i], search);
                CFRelease(search);
            }

            if (path == NULL) {
                CFStringRef search = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)/%@"), version, build, suffix);
                path = copy_xcode_path_for(deviceClassPath[i], search);
                CFRelease(search);
            }
            
            if (path == NULL) {
                CFStringRef search = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (*)/%@"), version, suffix);
                path = copy_xcode_path_for(deviceClassPath[i], search);
                CFRelease(search);
            }
            
            if (path == NULL) {
                CFStringRef search = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), version, suffix);
                path = copy_xcode_path_for(deviceClassPath[i], search);
                CFRelease(search);
            }

            if (path == NULL) {
                CFStringRef search = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.*/%@"), version, suffix);
                path = copy_xcode_path_for(deviceClassPath[i], search);
                CFRelease(search);
            }
            if (path == NULL) {
                CFStringRef search = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ %@ (%@)/%@"), productType, version, build, suffix);
                path = copy_xcode_path_for(deviceClassPath[i], search);
                CFRelease(search);
            }
        }
        
        CFRelease(version);
        if (path != NULL) {
            break;
        }
        CFArrayRemoveValueAtIndex(version_parts, CFArrayGetCount(version_parts) - 1);
    }
    
    for( int i = 0; i < 2; ++i ) {
        if (path == NULL) {
            CFStringRef search = CFStringCreateWithFormat(NULL, NULL, CFSTR("Latest/%@"), suffix);
            path = copy_xcode_path_for(deviceClassPath[i], search);
            CFRelease(search);
        }
    }

    CFRelease(version_parts);
    CFRelease(build);
    CFRelease(deviceClass);
    CFRelease(productType);
    if (deviceModel != NULL) {
        CFRelease(deviceModel);
    }
    if (path == NULL) {
      NSString *msg = [NSString stringWithFormat:@"Unable to locate DeviceSupport directory with suffix '%@'. This probably means you don't have Xcode installed, you will need to launch the app manually and logging output will not be shown!", suffix];
        NSLogJSON(@{
          @"Event": @"DeviceSupportError",
          @"Status": msg,
        });
        on_error(msg);
    }
    
    time( &endTime );
    NSLogVerbose(@"DeviceSupport directory '%@' was located. It took %.2f seconds", path, difftime(endTime,startTime));
    
    return path;
}

void mount_callback(CFDictionaryRef dict, int arg) {
    CFStringRef status = CFDictionaryGetValue(dict, CFSTR("Status"));

    if (CFEqual(status, CFSTR("LookingUpImage"))) {
        NSLogOut(@"[  0%%] Looking up developer disk image");
    } else if (CFEqual(status, CFSTR("CopyingImage"))) {
        NSLogOut(@"[ 30%%] Copying DeveloperDiskImage.dmg to device");
    } else if (CFEqual(status, CFSTR("MountingImage"))) {
        NSLogOut(@"[ 90%%] Mounting developer disk image");
    }
}

void mount_developer_image(AMDeviceRef device) {
    CFStringRef image_path = copy_device_support_path(device, CFSTR("DeveloperDiskImage.dmg"));
    CFStringRef sig_path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.signature"), image_path);

    NSLogVerbose(@"Developer disk image: %@", image_path);

    FILE* sig = fopen(CFStringGetCStringPtr(sig_path, kCFStringEncodingMacRoman), "rb");
    size_t buf_size = 128;
    void *sig_buf = malloc(buf_size);
    size_t bytes_read = fread(sig_buf, 1, buf_size, sig);
    if (bytes_read != buf_size) {
      on_sys_error(@"fread read %d bytes but expected %d bytes.", bytes_read, buf_size);
    }
    fclose(sig);
    CFDataRef sig_data = CFDataCreateWithBytesNoCopy(NULL, sig_buf, buf_size, NULL);
    CFRelease(sig_path);

    CFTypeRef keys[] = { CFSTR("ImageSignature"), CFSTR("ImageType") };
    CFTypeRef values[] = { sig_data, CFSTR("Developer") };
    CFDictionaryRef options = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFRelease(sig_data);

    unsigned int result = (unsigned int)AMDeviceMountImage(device, image_path, options, &mount_callback, 0);
    if (result == 0) {
        NSLogOut(@"[ 95%%] Developer disk image mounted successfully");
    } else if (result == 0xe8000076 /* already mounted */) {
        NSLogOut(@"[ 95%%] Developer disk image already mounted");
    } else {
        if (result != 0) {
            const char* msg = get_error_message(result);
            NSString *description = @"unknown.";
            if (msg) {
                description = [NSString stringWithUTF8String:msg];
                NSLogOut(@"Error: %@", description);
            }
            NSLogJSON(@{@"Event": @"Error",
                        @"Code": @(result),
                        @"Status": description});
        }
        
        on_error(@"Unable to mount developer disk image. (%x)", result);
    }
  
    CFStringRef symbols_path = copy_device_support_path(device, CFSTR("Symbols"));
    if (symbols_path != NULL)
    {
        NSLogOut(@"Symbol Path: %@", symbols_path);
        NSLogJSON(@{@"Event": @"MountDeveloperImage",
                    @"SymbolsPath": (__bridge NSString *)symbols_path
                    });
        CFRelease(symbols_path);
    }
  
    CFRelease(image_path);
    CFRelease(options);
}

mach_error_t transfer_callback(CFDictionaryRef dict, int arg) {
    if (CFDictionaryGetValue(dict, CFSTR("Error"))) {
        return 0;
    }
    int percent;
    CFStringRef status = CFDictionaryGetValue(dict, CFSTR("Status"));
    CFNumberGetValue(CFDictionaryGetValue(dict, CFSTR("PercentComplete")), kCFNumberSInt32Type, &percent);

    if (CFEqual(status, CFSTR("CopyingFile"))) {
        static CFStringRef last_path = NULL;
        static int last_overall_percent = -1;

        CFStringRef path = CFDictionaryGetValue(dict, CFSTR("Path"));
        int overall_percent = percent / 2;

        if ((last_path == NULL || !CFEqual(path, last_path) || last_overall_percent != overall_percent) && !CFStringHasSuffix(path, CFSTR(".ipa"))) {
            NSLogOut(@"[%3d%%] Copying %@ to device", overall_percent, path);
            NSLogJSON(@{@"Event": @"BundleCopy",
                        @"OverallPercent": @(overall_percent),
                        @"Percent": @(percent),
                        @"Path": (__bridge NSString *)path
                        });
        }

        last_overall_percent = overall_percent;

        if (last_path != NULL) {
            CFRelease(last_path);
        }
        last_path = CFStringCreateCopy(NULL, path);
    }

    return 0;
}

mach_error_t install_callback(CFDictionaryRef dict, int arg) {
    if (CFDictionaryGetValue(dict, CFSTR("Error"))) {
        return 0;
    }
    int percent;
    CFStringRef status = CFDictionaryGetValue(dict, CFSTR("Status"));
    CFNumberGetValue(CFDictionaryGetValue(dict, CFSTR("PercentComplete")), kCFNumberSInt32Type, &percent);

    int overall_percent = (percent / 2) + 50;
    NSLogOut(@"[%3d%%] %@", overall_percent, status);
    NSLogJSON(@{@"Event": @"BundleInstall",
                @"OverallPercent": @(overall_percent),
                @"Percent": @(percent),
                @"Status": (__bridge NSString *)status
                });
    return 0;
}

// During standard installation transferring and installation takes place
// in distinct function that can be passed distinct callbacks. Incremental
// installation performs both transfer and installation in a single function so
// use this callback to determine which step is occuring and call the proper
// callback.
mach_error_t incremental_install_callback(CFDictionaryRef dict, int arg) {
    if (CFDictionaryGetValue(dict, CFSTR("Error"))) {
        return 0;
    }
    CFStringRef status = CFDictionaryGetValue(dict, CFSTR("Status"));
    if (CFEqual(status, CFSTR("TransferringPackage"))) {
        int percent;
        CFNumberGetValue(CFDictionaryGetValue(dict, CFSTR("PercentComplete")), kCFNumberSInt32Type, &percent);
        int overall_percent = (percent / 2);
        NSLogOut(@"[%3d%%] %@", overall_percent, status);
        NSLogJSON(@{@"Event": @"TransferringPackage",
                    @"OverallPercent": @(overall_percent),
                    });
        return 0;
    } else if (CFEqual(status, CFSTR("CopyingFile"))) {
        return transfer_callback(dict, arg);
    } else {
        return install_callback(dict, arg);
    }
}

CFURLRef copy_device_app_url(AMDeviceRef device, CFStringRef identifier) {
    CFDictionaryRef result = nil;

    NSArray *a = [NSArray arrayWithObjects:
                  @"CFBundleIdentifier",            // absolute must
                  @"ApplicationDSID",
                  @"ApplicationType",
                  @"CFBundleExecutable",
                  @"CFBundleDisplayName",
                  @"CFBundleIconFile",
                  @"CFBundleName",
                  @"CFBundleShortVersionString",
                  @"CFBundleSupportedPlatforms",
                  @"CFBundleURLTypes",
                  @"CodeInfoIdentifier",
                  @"Container",
                  @"Entitlements",
                  @"HasSettingsBundle",
                  @"IsUpgradeable",
                  @"MinimumOSVersion",
                  @"Path",
                  @"SignerIdentity",
                  @"UIDeviceFamily",
                  @"UIFileSharingEnabled",
                  @"UIStatusBarHidden",
                  @"UISupportedInterfaceOrientations",
                  nil];

    NSDictionary *optionsDict = [NSDictionary dictionaryWithObject:a forKey:@"ReturnAttributes"];
    CFDictionaryRef options = (CFDictionaryRef)optionsDict;

    check_error(AMDeviceLookupApplications(device, options, &result));

    CFDictionaryRef app_dict = CFDictionaryGetValue(result, identifier);
    assert(app_dict != NULL);

    CFStringRef app_path = CFDictionaryGetValue(app_dict, CFSTR("Path"));
    assert(app_path != NULL);

    CFURLRef url = CFURLCreateWithFileSystemPath(NULL, app_path, kCFURLPOSIXPathStyle, true);
    CFRelease(result);
    return url;
}

CFStringRef copy_disk_app_identifier(CFURLRef disk_app_url) {
    CFURLRef plist_url = CFURLCreateCopyAppendingPathComponent(NULL, disk_app_url, CFSTR("Info.plist"), false);
    CFReadStreamRef plist_stream = CFReadStreamCreateWithFile(NULL, plist_url);
    if (!CFReadStreamOpen(plist_stream)) {
        on_error(@"Cannot read Info.plist file: %@", plist_url);
    }

    CFPropertyListRef plist = CFPropertyListCreateWithStream(NULL, plist_stream, 0, kCFPropertyListImmutable, NULL, NULL);
    CFStringRef bundle_identifier = CFRetain(CFDictionaryGetValue(plist, CFSTR("CFBundleIdentifier")));
    CFReadStreamClose(plist_stream);

    CFRelease(plist_url);
    CFRelease(plist_stream);
    CFRelease(plist);

    return bundle_identifier;
}

CFStringRef copy_modules_search_paths_pairs(CFStringRef symbols_path, CFStringRef disk_container, CFStringRef device_container_private, CFStringRef device_container_noprivate )
{
    CFMutableStringRef res = CFStringCreateMutable(kCFAllocatorDefault, 0);
    CFStringAppendFormat(res, NULL, CFSTR("/usr \"%@/usr\""), symbols_path);
    CFStringAppendFormat(res, NULL, CFSTR(" /System \"%@/System\""), symbols_path);
    CFStringAppendFormat(res, NULL, CFSTR(" \"%@\" \"%@\""), device_container_private, disk_container);
    CFStringAppendFormat(res, NULL, CFSTR(" \"%@\" \"%@\""), device_container_noprivate, disk_container);
    CFStringAppendFormat(res, NULL, CFSTR(" /Developer \"%@/Developer\""), symbols_path);
    
    return res;
}

CFStringRef get_device_platform(AMDeviceRef device)
{
    CFStringRef deviceClass = AMDeviceCopyValue(device, 0, CFSTR("DeviceClass"));
    CFStringRef platform;
    if (CFStringCompare(CFSTR("AppleTV"), deviceClass, 0) == kCFCompareEqualTo) {
        platform = CFSTR("tvos");
    }
    else if (CFStringCompare(CFSTR("Watch"), deviceClass, 0) == kCFCompareEqualTo) {
        platform = CFSTR("watchos");
    }
    else {
        platform = CFSTR("ios");
    }
    CFRelease(deviceClass);
    return platform;
}

void write_lldb_prep_cmds(AMDeviceRef device, CFURLRef disk_app_url) {
    CFStringRef symbols_path = copy_device_support_path(device, CFSTR("Symbols"));
    CFMutableStringRef cmds = CFStringCreateMutableCopy(NULL, 0, LLDB_PREP_CMDS);
    CFRange range = { 0, CFStringGetLength(cmds) };

    CFStringFindAndReplace(cmds, CFSTR("{platform}"), get_device_platform(device), range, 0);
    range.length = CFStringGetLength(cmds);

    CFStringFindAndReplace(cmds, CFSTR("{symbols_path}"), symbols_path, range, 0);
    range.length = CFStringGetLength(cmds);

    CFMutableStringRef pmodule = CFStringCreateMutableCopy(NULL, 0, (CFStringRef)LLDB_FRUITSTRAP_MODULE);

    CFRange rangeLLDB = { 0, CFStringGetLength(pmodule) };
    
    CFStringRef exitcode_app_crash_str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), exitcode_app_crash);
    CFStringFindAndReplace(pmodule, CFSTR("{exitcode_app_crash}"), exitcode_app_crash_str, rangeLLDB, 0);
    CFRelease(exitcode_app_crash_str);
    rangeLLDB.length = CFStringGetLength(pmodule);
    
    CFStringRef detect_deadlock_timeout_str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), _detectDeadlockTimeout);
    CFStringFindAndReplace(pmodule, CFSTR("{detect_deadlock_timeout}"), detect_deadlock_timeout_str, rangeLLDB, 0);
    CFRelease(detect_deadlock_timeout_str);
    rangeLLDB.length = CFStringGetLength(pmodule);

    if (args) {
        CFStringRef cf_args = CFStringCreateWithCString(NULL, args, kCFStringEncodingUTF8);
        CFStringFindAndReplace(cmds, CFSTR("{args}"), cf_args, range, 0);
        rangeLLDB.length = CFStringGetLength(pmodule);
        CFStringFindAndReplace(pmodule, CFSTR("{args}"), cf_args, rangeLLDB, 0);

        //printf("write_lldb_prep_cmds:args: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
        //    CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
        CFRelease(cf_args);
    } else {
        CFStringFindAndReplace(cmds, CFSTR("{args}"), CFSTR(""), range, 0);
        CFStringFindAndReplace(pmodule, CFSTR("{args}"), CFSTR(""), rangeLLDB, 0);
        //printf("write_lldb_prep_cmds: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
        //    CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
    }

    if (envs) {
        CFStringRef cf_envs = CFStringCreateWithCString(NULL, envs, kCFStringEncodingUTF8);
        CFStringFindAndReplace(cmds, CFSTR("{envs}"), cf_envs, range, 0);
        rangeLLDB.length = CFStringGetLength(pmodule);
        CFStringFindAndReplace(pmodule, CFSTR("{envs}"), cf_envs, rangeLLDB, 0);

        //printf("write_lldb_prep_cmds:envs: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
        //    CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
        CFRelease(cf_envs);
    } else {
        CFStringFindAndReplace(cmds, CFSTR("{envs}"), CFSTR(""), range, 0);
        CFStringFindAndReplace(pmodule, CFSTR("{envs}"), CFSTR(""), rangeLLDB, 0);
        //printf("write_lldb_prep_cmds: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
        //    CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
    }
    range.length = CFStringGetLength(cmds);

    CFStringRef bundle_identifier = copy_disk_app_identifier(disk_app_url);
    CFURLRef device_app_url = copy_device_app_url(device, bundle_identifier);
    CFRelease(bundle_identifier);
    CFStringRef device_app_path = CFURLCopyFileSystemPath(device_app_url, kCFURLPOSIXPathStyle);
    CFStringFindAndReplace(cmds, CFSTR("{device_app}"), device_app_path, range, 0);
    CFRelease(device_app_path);
    range.length = CFStringGetLength(cmds);

    CFStringRef disk_app_path = CFURLCopyFileSystemPath(disk_app_url, kCFURLPOSIXPathStyle);
    CFStringFindAndReplace(cmds, CFSTR("{disk_app}"), disk_app_path, range, 0);
    CFRelease(disk_app_path);
    range.length = CFStringGetLength(cmds);

    CFStringRef device_port = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), port);
    CFStringFindAndReplace(cmds, CFSTR("{device_port}"), device_port, range, 0);
    CFRelease(device_port);
    range.length = CFStringGetLength(cmds);

    if (output_path) {
        CFStringRef output_path_str = CFStringCreateWithCString(NULL, output_path, kCFStringEncodingUTF8);
        CFStringFindAndReplace(cmds, CFSTR("{output_path}"), output_path_str, range, 0);
        CFRelease(output_path_str);
    } else {
        CFStringFindAndReplace(cmds, CFSTR("{output_path}"), CFSTR(""), range, 0);
    }
    range.length = CFStringGetLength(cmds);
    if (error_path) {
        CFStringRef error_path_str = CFStringCreateWithCString(NULL, error_path, kCFStringEncodingUTF8);
        CFStringFindAndReplace(cmds, CFSTR("{error_path}"), error_path_str, range, 0);
        CFRelease(error_path_str);
    } else {
        CFStringFindAndReplace(cmds, CFSTR("{error_path}"), CFSTR(""), range, 0);
    }
    range.length = CFStringGetLength(cmds);

    CFURLRef device_container_url = CFURLCreateCopyDeletingLastPathComponent(NULL, device_app_url);
    CFRelease(device_app_url);
    CFStringRef device_container_path = CFURLCopyFileSystemPath(device_container_url, kCFURLPOSIXPathStyle);
    CFRelease(device_container_url);
    CFMutableStringRef dcp_noprivate = CFStringCreateMutableCopy(NULL, 0, device_container_path);
    range.length = CFStringGetLength(dcp_noprivate);
    CFStringFindAndReplace(dcp_noprivate, CFSTR("/private/var/"), CFSTR("/var/"), range, 0);
    range.length = CFStringGetLength(cmds);
    CFStringFindAndReplace(cmds, CFSTR("{device_container}"), dcp_noprivate, range, 0);
    range.length = CFStringGetLength(cmds);

    CFURLRef disk_container_url = CFURLCreateCopyDeletingLastPathComponent(NULL, disk_app_url);
    CFStringRef disk_container_path = CFURLCopyFileSystemPath(disk_container_url, kCFURLPOSIXPathStyle);
    CFRelease(disk_container_url);
    CFStringFindAndReplace(cmds, CFSTR("{disk_container}"), disk_container_path, range, 0);
    range.length = CFStringGetLength(cmds);
    
    CFStringRef search_paths_pairs = copy_modules_search_paths_pairs(symbols_path, disk_container_path, device_container_path, dcp_noprivate);
    CFRelease(symbols_path);
    CFRelease(device_container_path);
    CFRelease(dcp_noprivate);
    CFRelease(disk_container_path);
    CFStringFindAndReplace(cmds, CFSTR("{modules_search_paths_pairs}"), search_paths_pairs, range, 0);
    range.length = CFStringGetLength(cmds);
    CFRelease(search_paths_pairs);
    
    NSString* python_file_path = [NSString stringWithFormat:@"/tmp/%@/fruitstrap_", tmpUUID];
    mkdirp(python_file_path);

    NSString* python_command = @"fruitstrap_";
    if(device_id != NULL) {
        python_file_path = [python_file_path stringByAppendingString:[[NSString stringWithUTF8String:device_id] stringByReplacingOccurrencesOfString:@"-" withString:@"_"]];
        python_command = [python_command stringByAppendingString:[[NSString stringWithUTF8String:device_id] stringByReplacingOccurrencesOfString:@"-" withString:@"_"]];
    }
    python_file_path = [python_file_path stringByAppendingString:@".py"];

    CFStringFindAndReplace(cmds, CFSTR("{python_command}"), (CFStringRef)python_command, range, 0);
    range.length = CFStringGetLength(cmds);
    CFStringFindAndReplace(cmds, CFSTR("{python_file_path}"), (CFStringRef)python_file_path, range, 0);
    range.length = CFStringGetLength(cmds);

    CFDataRef cmds_data = CFStringCreateExternalRepresentation(NULL, cmds, kCFStringEncodingUTF8, 0);
    NSString* prep_cmds_path = [NSString stringWithFormat:PREP_CMDS_PATH, tmpUUID];
    if(device_id != NULL) {
        prep_cmds_path = [prep_cmds_path stringByAppendingString:[[NSString stringWithUTF8String:device_id] stringByReplacingOccurrencesOfString:@"-" withString:@"_"]];
    }
    FILE *out = fopen([prep_cmds_path UTF8String], "w");
    fwrite(CFDataGetBytePtr(cmds_data), CFDataGetLength(cmds_data), 1, out);
    CFRelease(cmds_data);
    // Write additional commands based on mode we're running in
    const char* extra_cmds;
    if (!interactive)
    {
        if (justlaunch)
          extra_cmds = lldb_prep_noninteractive_justlaunch_cmds;
        else
          extra_cmds = lldb_prep_noninteractive_cmds;
    }
    else if (nostart)
        extra_cmds = lldb_prep_no_cmds;
    else
        extra_cmds = lldb_prep_interactive_cmds;
    fwrite(extra_cmds, strlen(extra_cmds), 1, out);
    if (custom_commands != nil)
    {
        const char * cmds = [custom_commands UTF8String];
        fwrite(cmds, 1, strlen(cmds), out);
    }
    fclose(out);


    out = fopen([python_file_path UTF8String], "w");
    CFDataRef pmodule_data = CFStringCreateExternalRepresentation(NULL, pmodule, kCFStringEncodingUTF8, 0);
    fwrite(CFDataGetBytePtr(pmodule_data), CFDataGetLength(pmodule_data), 1, out);
    CFRelease(pmodule_data);

    if (custom_script_path)
    {
        FILE * fh = fopen(custom_script_path, "r");
        if (fh == NULL)
        {
            on_error(@"Failed to open %s", custom_script_path);
        }
        fwrite("\n", 1, 1, out);
        char buffer[0x1000];
        size_t bytesRead;
        while ((bytesRead = fread(buffer, 1, sizeof(buffer), fh)) > 0)
        {
            fwrite(buffer, 1, bytesRead, out);
        }
        fclose(fh);
    }

    fclose(out);

    CFRelease(cmds);
    CFRelease(pmodule);
}

CFSocketRef server_socket;
CFSocketRef lldb_socket;
CFWriteStreamRef serverWriteStream = NULL;
CFWriteStreamRef lldbWriteStream = NULL;

int kill_ptree(pid_t root, int signum);
void
server_callback (CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)
{
    char buffer[0x1000];
    int bytesRead = AMDServiceConnectionReceive(dbgServiceConnection, buffer, sizeof(buffer));
    if (bytesRead == 0)
    {
        // close the socket on which we've got end-of-file, the server_socket.
        CFSocketInvalidate(s);
        CFRelease(s);
        return;
    }
    write(CFSocketGetNative (lldb_socket), buffer, bytesRead);
    while (bytesRead == sizeof(buffer))
    {
        bytesRead = AMDServiceConnectionReceive(dbgServiceConnection, buffer, sizeof(buffer));
        if (bytesRead > 0)
        {
            write(CFSocketGetNative (lldb_socket), buffer, bytesRead);
        }
    }
}

void lldb_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)
{
    //printf ("lldb: %s\n", CFDataGetBytePtr (data));

    if (CFDataGetLength (data) == 0) {
        // close the socket on which we've got end-of-file, the lldb_socket.
        CFSocketInvalidate(s);
        CFRelease(s);
        return;
    }
    int __unused sent = AMDServiceConnectionSend(dbgServiceConnection, CFDataGetBytePtr(data),  CFDataGetLength (data));
    assert (CFDataGetLength (data) == sent);
}

void fdvendor_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info) {
    CFSocketNativeHandle socket = (CFSocketNativeHandle)(*((CFSocketNativeHandle *)data));

    assert (callbackType == kCFSocketAcceptCallBack);
    //PRINT ("callback!\n");

    lldb_socket  = CFSocketCreateWithNative(NULL, socket, kCFSocketDataCallBack, &lldb_callback, NULL);
    int flag = 1;
    int res = setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
    if (res == -1) {
      on_sys_error(@"Setting socket option failed.");
    }
    if (lldb_socket_runloop) {
        CFRelease(lldb_socket_runloop);
    }
    lldb_socket_runloop = CFSocketCreateRunLoopSource(NULL, lldb_socket, 0);
    CFRunLoopAddSource(CFRunLoopGetMain(), lldb_socket_runloop, kCFRunLoopCommonModes);

    CFSocketInvalidate(s);
    CFRelease(s);
}

void connect_and_start_session(AMDeviceRef device) {
    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    check_error(AMDeviceValidatePairing(device));
    check_error(AMDeviceStartSession(device));
}

void start_remote_debug_server(AMDeviceRef device) {

    dbgServiceConnection = NULL;
    CFStringRef serviceName = CFSTR("com.apple.debugserver");
    CFStringRef keys[] = { CFSTR("MinIPhoneVersion"), CFSTR("MinAppleTVVersion"), CFSTR("MinWatchVersion") };
    CFStringRef values[] = { CFSTR("14.0"), CFSTR("14.0"), CFSTR("7.0") }; // Not sure about older watchOS versions
    CFDictionaryRef version = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    bool useSecureProxy = AMDeviceIsAtLeastVersionOnPlatform(device, version);
    if (useSecureProxy)
    {
        serviceName = CFSTR("com.apple.debugserver.DVTSecureSocketProxy");
    }

    int start_err = AMDeviceSecureStartService(device, serviceName, NULL, &dbgServiceConnection);
    if (start_err != 0)
    {
        // After we mount the image, iOS needs to scan the image to register new services.
        // If we ask to start the service before it is found by ios, we will get 0xe8000022.
        // In other cases, it's been observed, that device may loose connection here (0xe800002d).
        // Luckly, we can just restart the connection and continue.
        // In other cases we just error out.
        NSLogOut(@"Failed to start debugserver: %x %s", start_err, get_error_message(start_err));
        switch(start_err)
        {
            case 0xe8000022:
                NSLogOut(@"Waiting for the device to scan mounted image");
                sleep(1);
                break;
            case 0x800002d:
                NSLogOut(@"Reconnecting to device");
                // We dont call AMDeviceStopSession as we cannot send any messages anymore
                check_error(AMDeviceDisconnect(device));
                connect_and_start_session(device);
                break;
            default:
                check_error(start_err);
        }
        check_error(AMDeviceSecureStartService(device, serviceName, NULL, &dbgServiceConnection));
    }
    assert(dbgServiceConnection != NULL);

    if (!useSecureProxy)
    {
        disable_ssl(dbgServiceConnection);
    }

    /*
     * The debugserver connection is through a fd handle, while lldb requires a host/port to connect, so create an intermediate
     * socket to transfer data.
     */
    server_socket = CFSocketCreateWithNative (NULL, AMDServiceConnectionGetSocket(dbgServiceConnection), kCFSocketReadCallBack, &server_callback, NULL);
    if (server_socket_runloop) {
        CFRelease(server_socket_runloop);
    }
    server_socket_runloop = CFSocketCreateRunLoopSource(NULL, server_socket, 0);
    CFRunLoopAddSource(CFRunLoopGetMain(), server_socket_runloop, kCFRunLoopCommonModes);

    struct sockaddr_in addr4;
    memset(&addr4, 0, sizeof(addr4));
    addr4.sin_len = sizeof(addr4);
    addr4.sin_family = AF_INET;
    addr4.sin_port = htons(port);
    addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    CFSocketRef fdvendor = CFSocketCreate(NULL, PF_INET, 0, 0, kCFSocketAcceptCallBack, &fdvendor_callback, NULL);

    if (port) {
        int yes = 1;
        setsockopt(CFSocketGetNative(fdvendor), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
    }

    CFDataRef address_data = CFDataCreate(NULL, (const UInt8 *)&addr4, sizeof(addr4));

    CFSocketSetAddress(fdvendor, address_data);
    CFRelease(address_data);
    socklen_t addrlen = sizeof(addr4);
    int res = getsockname(CFSocketGetNative(fdvendor),(struct sockaddr *)&addr4,&addrlen);
    if (res == -1) {
      on_sys_error(@"Getting socket name failed.");
    }
    port = ntohs(addr4.sin_port);

    if (fdvendor_runloop) {
        CFRelease(fdvendor_runloop);
    }
    fdvendor_runloop = CFSocketCreateRunLoopSource(NULL, fdvendor, 0);
    CFRunLoopAddSource(CFRunLoopGetMain(), fdvendor_runloop, kCFRunLoopCommonModes);
}

void kill_ptree_inner(pid_t root, int signum, struct kinfo_proc *kp, int kp_len) {
    int i;
    for (i = 0; i < kp_len; i++) {
        if (kp[i].kp_eproc.e_ppid == root) {
            kill_ptree_inner(kp[i].kp_proc.p_pid, signum, kp, kp_len);
        }
    }
    if (root != getpid()) {
        kill(root, signum);
    }
}

int kill_ptree(pid_t root, int signum) {
    int mib[3];
    size_t len;
    mib[0] = CTL_KERN;
    mib[1] = KERN_PROC;
    mib[2] = KERN_PROC_ALL;
    if (sysctl(mib, 3, NULL, &len, NULL, 0) == -1) {
        return -1;
    }

    struct kinfo_proc *kp = calloc(1, len);
    if (!kp) {
        return -1;
    }

    if (sysctl(mib, 3, kp, &len, NULL, 0) == -1) {
        free(kp);
        return -1;
    }

    kill_ptree_inner(root, signum, kp, (int)(len / sizeof(struct kinfo_proc)));

    free(kp);
    return 0;
}

void killed(int signum) {
    // SIGKILL needed to kill lldb, probably a better way to do this.
    kill(0, SIGKILL);
    _exit(0);
}

void lldb_finished_handler(int signum)
{
    int status = 0;
    if (waitpid(child, &status, 0) == -1)
        perror("waitpid failed");
    _exit(WEXITSTATUS(status));
}

pid_t bring_process_to_foreground(void) {
    pid_t fgpid = tcgetpgrp(STDIN_FILENO);
    if (setpgid(0, 0) == -1)
        perror("setpgid failed");

    signal(SIGTTOU, SIG_IGN);
    if (tcsetpgrp(STDIN_FILENO, getpid()) == -1)
        perror("tcsetpgrp failed");
    signal(SIGTTOU, SIG_DFL);
    return fgpid;
}

void setup_dummy_pipe_on_stdin(int pfd[2]) {
    if (pipe(pfd) == -1)
        perror("pipe failed");
    if (dup2(pfd[0], STDIN_FILENO) == -1)
        perror("dup2 failed");
}

void setup_lldb(AMDeviceRef device, CFURLRef url) {
    CFStringRef device_full_name = get_device_full_name(device),
    device_interface_name = get_device_interface_name(device);

    connect_and_start_session(device);

    NSLogOut(@"------ Debug phase ------");

    NSLogOut(@"Starting debug of %@ connected through %@...", device_full_name, device_interface_name);

    mount_developer_image(device);      // put debugserver on the device
    start_remote_debug_server(device);  // start debugserver
    if (!debugserver_only)
        write_lldb_prep_cmds(device, url);   // dump the necessary lldb commands into a file
    if (url != NULL)
        CFRelease(url);

    NSLogOut(@"[100%%] Connecting to remote debug server");
    NSLogOut(@"-------------------------");

    setpgid(getpid(), 0);
    signal(SIGHUP, killed);
    signal(SIGINT, killed);
    signal(SIGTERM, killed);
    // Need this before fork to avoid race conditions. For child process we remove this right after fork.
    signal(SIGLLDB, lldb_finished_handler);

    parent = getpid();
}

void launch_debugger(AMDeviceRef device, CFURLRef url) {
    setup_lldb(device, url);
    int pid = fork();
    if (pid == 0) {
        signal(SIGHUP, SIG_DFL);
        signal(SIGLLDB, SIG_DFL);
        child = getpid();
        pid_t oldfgpid = 0;
        int pfd[2] = {-1, -1};
        if (isatty(STDIN_FILENO))
            // If we are running on a terminal, then we need to bring process to foreground for input
            // to work correctly on lldb's end.
            oldfgpid = bring_process_to_foreground();
        else
            // If lldb is running in a non terminal environment, then it freaks out spamming "^D" and
            // "quit". It seems this is caused by read() on stdin returning EOF in lldb. To hack around
            // this we setup a dummy pipe on stdin, so read() would block expecting "user's" input.
            setup_dummy_pipe_on_stdin(pfd);

        NSString* lldb_shell;
        NSString* prep_cmds = [NSString stringWithFormat:PREP_CMDS_PATH, tmpUUID];
        lldb_shell = [NSString stringWithFormat:LLDB_SHELL, prep_cmds];

        if(device_id != NULL) {
            lldb_shell = [lldb_shell stringByAppendingString: [[NSString stringWithUTF8String:device_id] stringByReplacingOccurrencesOfString:@"-" withString:@"_"]];
        }

        int status = system([lldb_shell UTF8String]); // launch lldb
        if (status == -1)
            perror("failed launching lldb");

        close(pfd[0]);
        close(pfd[1]);

        // Notify parent we're exiting
        kill(parent, SIGLLDB);

        if (oldfgpid) {
            tcsetpgrp(STDIN_FILENO, oldfgpid);
        }
        // Pass lldb exit code
        _exit(WEXITSTATUS(status));
    } else if (pid > 0) {
        child = pid;
    } else {
        on_sys_error(@"Fork failed");
    }
}

void launch_debugger_and_exit(AMDeviceRef device, CFURLRef url) {
    setup_lldb(device,url);
    int pfd[2] = {-1, -1};
    if (pipe(pfd) == -1)
        perror("Pipe failed");
    int pid = fork();
    if (pid == 0) {
        signal(SIGHUP, SIG_DFL);
        signal(SIGLLDB, SIG_DFL);
        child = getpid();

        if (dup2(pfd[0],STDIN_FILENO) == -1)
            perror("dup2 failed");


        NSString* prep_cmds = [NSString stringWithFormat:PREP_CMDS_PATH, tmpUUID];
        NSString* lldb_shell = [NSString stringWithFormat:LLDB_SHELL, prep_cmds];
        if(device_id != NULL) {
            lldb_shell = [lldb_shell stringByAppendingString:[[NSString stringWithUTF8String:device_id] stringByReplacingOccurrencesOfString:@"-" withString:@"_"]];
        }

        int status = system([lldb_shell UTF8String]); // launch lldb
        if (status == -1)
            perror("failed launching lldb");

        close(pfd[0]);

        // Notify parent we're exiting
        kill(parent, SIGLLDB);
        // Pass lldb exit code
        _exit(WEXITSTATUS(status));
    } else if (pid > 0) {
        child = pid;
        NSLogVerbose(@"Waiting for child [Child: %d][Parent: %d]\n", child, parent);
    } else {
        on_sys_error(@"Fork failed");
    }
}

void launch_debugserver_only(AMDeviceRef device, CFURLRef url)
{
    if (url != NULL)
      CFRetain(url);
    setup_lldb(device,url);

    CFStringRef device_app_path = NULL;
    if (url != NULL) {
      CFStringRef bundle_identifier = copy_disk_app_identifier(url);
      CFURLRef device_app_url = copy_device_app_url(device, bundle_identifier);
      CFRelease(bundle_identifier);
      device_app_path = CFURLCopyFileSystemPath(device_app_url, kCFURLPOSIXPathStyle);
      CFRelease(device_app_url);
      CFRelease(url);
    }

    NSLogOut(@"debugserver port: %d", port);
    if (device_app_path == NULL) {
        NSLogJSON(@{@"Event": @"DebugServerLaunched",
                    @"Port": @(port),
                    });
    } else {
        NSLogOut(@"App path: %@", device_app_path);
        NSLogJSON(@{@"Event": @"DebugServerLaunched",
                    @"Port": @(port),
                    @"Path": (__bridge NSString *)device_app_path
                    });
        CFRelease(device_app_path);
    }
}

CFStringRef copy_bundle_id(CFURLRef app_url)
{
    if (app_url == NULL)
        return NULL;

    CFURLRef url = CFURLCreateCopyAppendingPathComponent(NULL, app_url, CFSTR("Info.plist"), false);

    if (url == NULL)
        return NULL;

    CFReadStreamRef stream = CFReadStreamCreateWithFile(NULL, url);
    CFRelease(url);

    if (stream == NULL)
        return NULL;

    CFPropertyListRef plist = NULL;
    if (CFReadStreamOpen(stream) == TRUE) {
        plist = CFPropertyListCreateWithStream(NULL, stream, 0,
                                               kCFPropertyListImmutable, NULL, NULL);
    }
    CFReadStreamClose(stream);
    CFRelease(stream);

    if (plist == NULL)
        return NULL;

    const void *value = CFDictionaryGetValue(plist, CFSTR("CFBundleIdentifier"));
    CFStringRef bundle_id = NULL;
    if (value != NULL)
        bundle_id = CFRetain(value);

    CFRelease(plist);
    return bundle_id;
}

typedef enum { READ_DIR_FILE, READ_DIR_FIFO, READ_DIR_BEFORE_DIR, READ_DIR_AFTER_DIR } read_dir_cb_reason;

void read_dir(AFCConnectionRef afc_conn_p, const char* dir,
              void(*callback)(AFCConnectionRef conn, const char *dir, read_dir_cb_reason reason))
{
    char *dir_ent;

    afc_dictionary* afc_dict_p;
    char *key, *val;
    int not_dir = 0;
    bool is_fifo = 0;

    unsigned int code = AFCFileInfoOpen(afc_conn_p, dir, &afc_dict_p);
    if (code != 0) {
        // there was a problem reading or opening the file to get info on it, abort
        return;
    }
    
    long long mtime = -1;
    long long birthtime = -1;
    long size = -1;
    long blocks = -1;
    long nlink = -1;
    NSString * ifmt = nil;
    while((AFCKeyValueRead(afc_dict_p,&key,&val) == 0) && key && val) {
        if (strcmp(key,"st_ifmt")==0) {
            not_dir = strcmp(val,"S_IFDIR");
            is_fifo = !strcmp(val, "S_IFIFO");
            if (_json_output) {
                ifmt = [NSString stringWithUTF8String:val];
            } else {
                break;
            }
        } else if (strcmp(key, "st_size") == 0) {
            size = atol(val);
        } else if (strcmp(key, "st_mtime") == 0) {
            mtime = atoll(val);
        } else if (strcmp(key, "st_birthtime") == 0) {
            birthtime = atoll(val);
        } else if (strcmp(key, "st_nlink") == 0) {
            nlink = atol(val);
        } else if (strcmp(key, "st_blocks") == 0) {
            blocks = atol(val);
        }
    }
    AFCKeyValueClose(afc_dict_p);
    
    if (_json_output) {
        if (_file_meta_info == nil) {
            _file_meta_info = [[NSMutableArray alloc] init];
        }
        [_file_meta_info addObject: @{@"full_path": [NSString stringWithUTF8String:dir],
                                      @"st_ifmt": ifmt,
                                      @"st_nlink": @(nlink),
                                      @"st_size": @(size),
                                      @"st_blocks": @(blocks),
                                      @"st_mtime": @(mtime),
                                      @"st_birthtime": @(birthtime)}];
    }
    
    if (not_dir) {
        if (callback) (*callback)(afc_conn_p, dir, is_fifo ? READ_DIR_FIFO : READ_DIR_FILE);
        return;
    }

    afc_directory* afc_dir_p;
    afc_error_t err = AFCDirectoryOpen(afc_conn_p, dir, &afc_dir_p);

    if (err != 0) {
        // Couldn't open dir - was probably a file
        return;
    }
    
    // Call the callback on the directory before processing its
    // contents. This is used by copy file callback, which needs to
    // create the directory on the host before attempting to copy
    // files into it.
    if (callback) (*callback)(afc_conn_p, dir, READ_DIR_BEFORE_DIR);

    while(true) {
        err = AFCDirectoryRead(afc_conn_p, afc_dir_p, &dir_ent);

        if (err != 0 || !dir_ent)
            break;

        if (strcmp(dir_ent, ".") == 0 || strcmp(dir_ent, "..") == 0)
            continue;

        char* dir_joined = malloc(strlen(dir) + strlen(dir_ent) + 2);
        strcpy(dir_joined, dir);
        if (dir_joined[strlen(dir)-1] != '/')
            strcat(dir_joined, "/");
        strcat(dir_joined, dir_ent);
        if (!(non_recursively && strcmp(list_root, dir) != 0)) {
            read_dir(afc_conn_p, dir_joined, callback);
        }
        free(dir_joined);
    }

    AFCDirectoryClose(afc_conn_p, afc_dir_p);
    
    // Call the callback on the directory after processing its
    // contents. This is used by the rmtree callback because it needs
    // to delete the directory's contents before the directory itself
    if (callback) (*callback)(afc_conn_p, dir, READ_DIR_AFTER_DIR);
}

AFCConnectionRef start_afc_service(AMDeviceRef device) {
    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    check_error(AMDeviceValidatePairing(device));
    check_error(AMDeviceStartSession(device));

    AFCConnectionRef conn = NULL;
    ServiceConnRef serviceConn = NULL;

    if (AMDeviceStartService(device, AMSVC_AFC, &serviceConn, 0) != MDERR_OK) {
        on_error(@"Unable to start file service!");
    }
    if (AFCConnectionOpen(serviceConn, 0, &conn) != MDERR_OK) {
        on_error(@"Unable to open connection!");
    }

    check_error(AMDeviceStopSession(device));
    check_error(AMDeviceDisconnect(device));
    return conn;
}

// Used to send files to app-specific sandbox (Documents dir)
AFCConnectionRef start_house_arrest_service(AMDeviceRef device) {
    connect_and_start_session(device);

    AFCConnectionRef conn = NULL;

    if (bundle_id == NULL) {
        on_error(@"Bundle id is not specified");
    }

    CFStringRef cf_bundle_id = CFStringCreateWithCString(NULL, bundle_id, kCFStringEncodingUTF8);
    CFStringRef keys[1];
    keys[0] = CFSTR("Command");
    CFStringRef values[1];
    values[0] = CFSTR("VendDocuments");
    CFDictionaryRef command = CFDictionaryCreate(kCFAllocatorDefault,
                                                 (void*)keys,
                                                 (void*)values,
                                                 1,
                                                 &kCFTypeDictionaryKeyCallBacks,
                                                 &kCFTypeDictionaryValueCallBacks);
    if (AMDeviceCreateHouseArrestService(device, cf_bundle_id, 0, &conn) != 0 &&
        AMDeviceCreateHouseArrestService(device, cf_bundle_id, command, &conn) != 0) {
        on_error(@"Unable to find bundle with id: %@", [NSString stringWithUTF8String:bundle_id]);
    }

    check_error(AMDeviceStopSession(device));
    check_error(AMDeviceDisconnect(device));
    CFRelease(cf_bundle_id);

    return conn;
}

// Uses realpath() to resolve any symlinks in a path. Returns the resolved
// path or the original path if an error occurs. This allocates memory for the
// resolved path and the caller is responsible for freeing it.
char *resolve_path(char *path)
{
  char buffer[PATH_MAX];
  // Use the original path if realpath() fails, otherwise use resolved value.
  char *resolved_path = realpath(path, buffer) == NULL ? path : buffer;
  char *new_path = malloc(strlen(resolved_path) + 1);
  strcpy(new_path, resolved_path);
  return new_path;
}

char const* get_filename_from_path(char const* path)
{
    char const*ptr = path + strlen(path);
    while (ptr > path)
    {
        if (*ptr == '/')
            break;
        --ptr;
    }
    if (ptr+1 >= path+strlen(path))
        return NULL;
    if (ptr == path)
        return ptr;
    return ptr+1;
}

void* read_file_to_memory(char const * path, size_t* file_size)
{
    struct stat buf;
    int err = stat(path, &buf);
    if (err < 0)
    {
        return NULL;
    }

    *file_size = buf.st_size;
    FILE* fd = fopen(path, "r");
    char* content = malloc(*file_size);
    if (*file_size != 0 && fread(content, *file_size, 1, fd) != 1)
    {
        fclose(fd);
        return NULL;
    }
    fclose(fd);
    return content;
}

void list_files_callback(AFCConnectionRef conn, const char *name, read_dir_cb_reason reason)
{
    if (reason == READ_DIR_FILE || reason == READ_DIR_FIFO) {
        NSLogOut(@"%@", [NSString stringWithUTF8String:name]);
    } else if (reason == READ_DIR_BEFORE_DIR) {
        NSLogOut(@"%@/", [NSString stringWithUTF8String:name]);
    }
}

void list_files(AMDeviceRef device)
{
    AFCConnectionRef afc_conn_p;
    if (file_system) {
        afc_conn_p = start_afc_service(device);
    } else {
        afc_conn_p = start_house_arrest_service(device);
    }
    assert(afc_conn_p);
    if (_json_output) {
        read_dir(afc_conn_p, list_root?list_root:"/", NULL);
        NSLogJSON(@{@"Event": @"FileListed",
                    @"Files": _file_meta_info});
    } else {
        read_dir(afc_conn_p, list_root?list_root:"/", list_files_callback);
    }
    
    check_error(AFCConnectionClose(afc_conn_p));
}

int app_exists(AMDeviceRef device)
{
    if (bundle_id == NULL) {
        NSLogOut(@"Bundle id is not specified.");
        return 1;
    }
    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    check_error(AMDeviceValidatePairing(device));
    check_error(AMDeviceStartSession(device));

    CFStringRef cf_bundle_id = CFStringCreateWithCString(NULL, bundle_id, kCFStringEncodingUTF8);

    NSArray *a = [NSArray arrayWithObjects:@"CFBundleIdentifier", nil];
    NSDictionary *optionsDict = [NSDictionary dictionaryWithObject:a forKey:@"ReturnAttributes"];
    CFDictionaryRef options = (CFDictionaryRef)optionsDict;
    CFDictionaryRef result = nil;
    check_error(AMDeviceLookupApplications(device, options, &result));

    bool appExists = CFDictionaryContainsKey(result, cf_bundle_id);
    NSLogOut(@"%@", appExists ? @"true" : @"false");
    CFRelease(cf_bundle_id);

    check_error(AMDeviceStopSession(device));
    check_error(AMDeviceDisconnect(device));
    if (appExists)
        return 0;
    return -1;
}

void get_battery_level(AMDeviceRef device)
{
    
    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    check_error(AMDeviceValidatePairing(device));
    check_error(AMDeviceStartSession(device));

    CFStringRef result = AMDeviceCopyValue(device, (void*)@"com.apple.mobile.battery", (__bridge CFStringRef)@"BatteryCurrentCapacity");
    NSLogOut(@"BatteryCurrentCapacity:%@",result);
    CFRelease(result);
    
    check_error(AMDeviceStopSession(device));
    check_error(AMDeviceDisconnect(device));
}

void replace_dict_date_with_absolute_time(CFMutableDictionaryRef dict, CFStringRef key) {
    CFDateRef date = CFDictionaryGetValue(dict, key);
    CFAbsoluteTime absolute_date = CFDateGetAbsoluteTime(date);
    CFNumberRef absolute_date_ref = CFNumberCreate(NULL, kCFNumberDoubleType, &absolute_date);
    CFDictionaryReplaceValue(dict, key, absolute_date_ref);
    CFRelease(absolute_date_ref);
}

void list_provisioning_profiles(AMDeviceRef device) {
    connect_and_start_session(device);
    CFArrayRef device_provisioning_profiles = AMDeviceCopyProvisioningProfiles(device);

    CFIndex provisioning_profiles_count = CFArrayGetCount(device_provisioning_profiles);
    CFMutableArrayRef serializable_provisioning_profiles =
        CFArrayCreateMutable(NULL, provisioning_profiles_count, &kCFTypeArrayCallBacks);

    for (CFIndex i = 0; i < provisioning_profiles_count; i++) {
        void *device_provisioning_profile =
            (void *)CFArrayGetValueAtIndex(device_provisioning_profiles, i);
        CFMutableDictionaryRef serializable_provisioning_profile;

        if (verbose) {
            // Verbose output; We selectively omit keys from profile.
            CFDictionaryRef immutable_profile_dict =
                MISProfileCopyPayload(device_provisioning_profile);
            serializable_provisioning_profile =
                CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, immutable_profile_dict);
            CFRelease(immutable_profile_dict);

            // Remove binary values from the output since they aren't readable and add a whole lot
            // of noise to the output.
            CFDictionaryRemoveValue(serializable_provisioning_profile,
                                    CFSTR("DER-Encoded-Profile"));
            CFDictionaryRemoveValue(serializable_provisioning_profile,
                                    CFSTR("DeveloperCertificates"));
        } else {
            // Normal output; We selectively include keys from profile.
            CFStringRef keys[] = {CFSTR("Name"), CFSTR("UUID"), CFSTR("ExpirationDate")};
            CFIndex size = sizeof(keys) / sizeof(CFStringRef);
            serializable_provisioning_profile =
                CFDictionaryCreateMutable(kCFAllocatorDefault, size, &kCFTypeDictionaryKeyCallBacks,
                                          &kCFTypeDictionaryValueCallBacks);
            for (CFIndex i = 0; i < size; i++) {
                CFStringRef key = keys[i];
                CFStringRef value = MISProfileGetValue(device_provisioning_profile, key);
                CFDictionaryAddValue(serializable_provisioning_profile, key, value);
            }
        }

        if (_json_output) {
            // JSON output can't have CFDate objects so convert dates into CFAbsoluteTime's.
            replace_dict_date_with_absolute_time(serializable_provisioning_profile,
                                                 CFSTR("ExpirationDate"));
            replace_dict_date_with_absolute_time(serializable_provisioning_profile,
                                                 CFSTR("CreationDate"));
        }

        CFArrayAppendValue(serializable_provisioning_profiles, serializable_provisioning_profile);
        CFRelease(serializable_provisioning_profile);
    }
    CFRelease(device_provisioning_profiles);

    if (_json_output) {
        NSLogJSON(@{
            @"Event" : @"ListProvisioningProfiles",
            @"Profiles" : (NSArray *)serializable_provisioning_profiles
        });
    } else {
        NSLogOut(@"%@", serializable_provisioning_profiles);
    }
    CFRelease(serializable_provisioning_profiles);
}

void install_provisioning_profile(AMDeviceRef device) {
    if (!profile_path) {
        on_error(@"no path to provisioning profile specified");
    }

    size_t file_size = 0;
    void *file_content = read_file_to_memory(profile_path, &file_size);
    CFDataRef profile_data = CFDataCreate(NULL, file_content, file_size);
    void *profile = MISProfileCreateWithData(0, profile_data);
    connect_and_start_session(device);
    check_error(AMDeviceInstallProvisioningProfile(device, profile));

    free(file_content);
    CFRelease(profile_data);
    CFRelease(profile);
}

void uninstall_provisioning_profile(AMDeviceRef device) {
    if (!profile_uuid) {
        on_error(@"no profile UUID specified via --profile-uuid");
    }

    CFStringRef uuid = CFStringCreateWithCString(NULL, profile_uuid, kCFStringEncodingUTF8);
    connect_and_start_session(device);
    check_error(AMDeviceRemoveProvisioningProfile(device, uuid));
    CFRelease(uuid);
}

void download_provisioning_profile(AMDeviceRef device) {
    if (!profile_uuid) {
        on_error(@"no profile UUID specified via --profile-uuid");
    } else if (!profile_path) {
        on_error(@"no download path specified");
    }

    connect_and_start_session(device);
    CFArrayRef device_provisioning_profiles = AMDeviceCopyProvisioningProfiles(device);
    CFIndex provisioning_profiles_count = CFArrayGetCount(device_provisioning_profiles);
    CFStringRef uuid = CFStringCreateWithCString(NULL, profile_uuid, kCFStringEncodingUTF8);
    bool found_matching_uuid = false;

    for (CFIndex i = 0; i < provisioning_profiles_count; i++) {
        void *profile = (void *)CFArrayGetValueAtIndex(device_provisioning_profiles, i);
        CFStringRef other_uuid = MISProfileGetValue(profile, CFSTR("UUID"));
        found_matching_uuid = CFStringCompare(uuid, other_uuid, 0) == kCFCompareEqualTo;

        if (found_matching_uuid) {
            NSLogVerbose(@"Writing %@ to %s", MISProfileGetValue(profile, CFSTR("Name")),
                         profile_path);
            CFStringRef dst_path =
                CFStringCreateWithCString(NULL, profile_path, kCFStringEncodingUTF8);
            check_error(MISProfileWriteToFile(profile, dst_path));
            CFRelease(dst_path);
            break;
        }
    }

    CFRelease(uuid);
    CFRelease(device_provisioning_profiles);
    if (!found_matching_uuid) {
        on_error(@"Did not find provisioning profile with UUID %x on device", profile_uuid);
    }
}

void list_bundle_id(AMDeviceRef device)
{
    connect_and_start_session(device);
    NSMutableArray *a = [NSMutableArray arrayWithObjects:
                         @"CFBundleIdentifier",
                         @"CFBundleName",
                         @"CFBundleDisplayName",
                         @"CFBundleVersion",
                         @"CFBundleShortVersionString", nil];
    if (keys) {
        for (NSString * key in keys) {
            [a addObjectsFromArray:[key componentsSeparatedByCharactersInSet:
                                    [NSCharacterSet characterSetWithCharactersInString:@",&"]]];
        }
    }
    NSDictionary *optionsDict = [NSDictionary dictionaryWithObject:a forKey:@"ReturnAttributes"];
    CFDictionaryRef options = (CFDictionaryRef)optionsDict;
    CFDictionaryRef result = nil;
    check_error(AMDeviceLookupApplications(device, options, &result));

    if (_json_output) {
        NSLogJSON(@{@"Event": @"ListBundleId",
                    @"Apps": (NSDictionary *)result});
    } else {
        CFIndex count;
        count = CFDictionaryGetCount(result);
        const void *keys[count];
        CFDictionaryGetKeysAndValues(result, keys, NULL);
        for(int i = 0; i < count; ++i) {
            NSLogOut(@"%@", (CFStringRef)keys[i]);
        }
    }

    check_error(AMDeviceStopSession(device));
    check_error(AMDeviceDisconnect(device));
}

void copy_file_callback(AFCConnectionRef afc_conn_p, const char *name, read_dir_cb_reason reason)
{
    const char *local_name=name;

    if (*local_name=='/') local_name++;

    if (*local_name=='\0') return;

    if (reason == READ_DIR_FILE || reason == READ_DIR_FIFO) {
        NSLogOut(@"%@", [NSString stringWithUTF8String:name]);
        afc_file_ref fref;
        int err = AFCFileRefOpen(afc_conn_p,name,1,&fref);

        if (err) {
            fprintf(stderr,"AFCFileRefOpen(\"%s\") failed: %d\n",name,err);
            return;
        }

        FILE *fp = fopen(local_name,"w");

        if (fp==NULL) {
            fprintf(stderr,"fopen(\"%s\",\"w\") failer: %s\n",local_name,strerror(errno));
            AFCFileRefClose(afc_conn_p,fref);
            return;
        }

        char buf[4096];
        size_t sz=sizeof(buf);

        while (AFCFileRefRead(afc_conn_p,fref,buf,&sz)==0 && sz) {
            fwrite(buf,sz,1,fp);
            sz = sizeof(buf);
        }

        AFCFileRefClose(afc_conn_p,fref);
        fclose(fp);

    } else if (reason == READ_DIR_BEFORE_DIR) {
        NSLogOut(@"%@/", [NSString stringWithUTF8String:name]);
        if (mkdir(local_name,0777) && errno!=EEXIST) {
            fprintf(stderr,"mkdir(\"%s\") failed: %s\n",local_name,strerror(errno));
        }
    }
}


void download_tree(AMDeviceRef device)
{
    AFCConnectionRef afc_conn_p;
    if (file_system) {
        afc_conn_p = start_afc_service(device);
    } else {
        afc_conn_p = start_house_arrest_service(device);
    }
    
    assert(afc_conn_p);
    char *dirname = NULL;

    list_root = list_root? list_root : "/";
    target_filename = target_filename? target_filename : ".";

    NSString* targetPath = [NSString pathWithComponents:@[ @(target_filename), @(list_root)] ];
    mkdirp([targetPath stringByDeletingLastPathComponent]);

    do {
        if (target_filename) {
            dirname = strdup(target_filename);
            mkdirp(@(dirname));
            if (mkdir(dirname,0777) && errno!=EEXIST) {
                fprintf(stderr,"mkdir(\"%s\") failed: %s\n",dirname,strerror(errno));
                break;
            }
            if (chdir(dirname)) {
                fprintf(stderr,"chdir(\"%s\") failed: %s\n",dirname,strerror(errno));
                break;
            }
        }
        read_dir(afc_conn_p, list_root, copy_file_callback);
    } while(0);

    if (dirname) free(dirname);
    if (afc_conn_p) AFCConnectionClose(afc_conn_p);
}

void upload_dir(AMDeviceRef device, AFCConnectionRef afc_conn_p, NSString* source, NSString* destination);
void upload_single_file(AMDeviceRef device, AFCConnectionRef afc_conn_p, NSString* sourcePath, NSString* destinationPath);

void upload_file(AMDeviceRef device)
{
    AFCConnectionRef afc_conn_p;
    if (file_system) {
        afc_conn_p = start_afc_service(device);
    } else {
        afc_conn_p = start_house_arrest_service(device);
    }
    assert(afc_conn_p);

    if (!target_filename)
    {
        target_filename = get_filename_from_path(upload_pathname);
    }

    NSString* sourcePath = [NSString stringWithUTF8String: upload_pathname];
    NSString* destinationPath = [NSString stringWithUTF8String: target_filename];

    BOOL isDir;
    bool exists = [[NSFileManager defaultManager] fileExistsAtPath: sourcePath isDirectory: &isDir];
    if (!exists)
    {
        on_error(@"Could not find file: %s", upload_pathname);
    }
    else if (isDir)
    {
        upload_dir(device, afc_conn_p, sourcePath, destinationPath);
    }
    else
    {
        upload_single_file(device, afc_conn_p, sourcePath, destinationPath);
    }
    check_error(AFCConnectionClose(afc_conn_p));
}

void upload_single_file(AMDeviceRef device, AFCConnectionRef afc_conn_p, NSString* sourcePath, NSString* destinationPath) {

    afc_file_ref file_ref;

    size_t file_size;
    void* file_content = read_file_to_memory([sourcePath fileSystemRepresentation], &file_size);

    if (!file_content)
    {
        on_error(@"Could not open file: %@", sourcePath);
    }

    // Make sure the directory was created
    {
        NSString *dirpath = [destinationPath stringByDeletingLastPathComponent];
        check_error(AFCDirectoryCreate(afc_conn_p, [dirpath fileSystemRepresentation]));
    }

    NSLogVerbose(@"%@", destinationPath);
    NSLogJSON(@{@"Event": @"UploadFile",
                @"Destination": destinationPath
                });

    int ret = AFCFileRefOpen(afc_conn_p, [destinationPath fileSystemRepresentation], 3, &file_ref);
    if (ret == 0x000a) {
        on_error(@"Cannot write to %@. Permission error.", destinationPath);
    }
    if (ret == 0x0009) {
        on_error(@"Target %@ is a directory.", destinationPath);
    }
    assert(ret == 0);
    check_error(AFCFileRefWrite(afc_conn_p, file_ref, file_content, file_size));
    check_error(AFCFileRefClose(afc_conn_p, file_ref));

    free(file_content);
}

void upload_dir(AMDeviceRef device, AFCConnectionRef afc_conn_p, NSString* source, NSString* destination)
{
    check_error(AFCDirectoryCreate(afc_conn_p, [destination fileSystemRepresentation]));
    for (NSString* item in [[NSFileManager defaultManager] contentsOfDirectoryAtPath: source error: nil])
    {
        NSString* sourcePath = [source stringByAppendingPathComponent: item];
        NSString* destinationPath = [destination stringByAppendingPathComponent: item];
        BOOL isDir;
        [[NSFileManager defaultManager] fileExistsAtPath: sourcePath isDirectory: &isDir];
        if (isDir)
        {
            NSString *dirDestinationPath = [destinationPath stringByAppendingString:@"/"];
            NSLogVerbose(@"%@", dirDestinationPath);
            NSLogJSON(@{@"Event": @"UploadDir",
                        @"Destination": dirDestinationPath
                        });
            upload_dir(device, afc_conn_p, sourcePath, destinationPath);
        }
        else
        {
            upload_single_file(device, afc_conn_p, sourcePath, destinationPath);
        }
    }
}

void make_directory(AMDeviceRef device) {
    AFCConnectionRef afc_conn_p;
    if (file_system) {
        afc_conn_p = start_afc_service(device);
    } else {
        afc_conn_p = start_house_arrest_service(device);
    }
    assert(afc_conn_p);
    check_error(AFCDirectoryCreate(afc_conn_p, target_filename));
    check_error(AFCConnectionClose(afc_conn_p));
}

void remove_path(AMDeviceRef device) {
    AFCConnectionRef afc_conn_p;
    if (file_system) {
        afc_conn_p = start_afc_service(device);
    } else {
        afc_conn_p = start_house_arrest_service(device);
    }
    assert(afc_conn_p);
    check_error(AFCRemovePath(afc_conn_p, target_filename));
    check_error(AFCConnectionClose(afc_conn_p));
}

// Handles the READ_DIR_AFTER_DIR callback so that we delete the contents of the
// directory before the directory itself
void rmtree_callback(AFCConnectionRef conn, const char *name, read_dir_cb_reason reason)
{
    if (reason == READ_DIR_FILE || reason == READ_DIR_AFTER_DIR) {
        NSLogVerbose(@"Deleting %s", name);
        log_error(AFCRemovePath(conn, name));
    } else if (reason == READ_DIR_FIFO) {
        NSLogVerbose(@"Skipping %s", name);
    }
}

void rmtree(AMDeviceRef device) {
    AFCConnectionRef afc_conn_p = start_house_arrest_service(device);
    assert(afc_conn_p);
    read_dir(afc_conn_p, target_filename, rmtree_callback);
    check_error(AFCConnectionClose(afc_conn_p));
}

void uninstall_app(AMDeviceRef device) {
    CFRetain(device); // don't know if this is necessary?

    NSLogOut(@"------ Uninstall phase ------");

    //Do we already have the bundle_id passed in via the command line? if so, use it.
    CFStringRef cf_uninstall_bundle_id = NULL;
    if (bundle_id != NULL)
    {
        cf_uninstall_bundle_id = CFStringCreateWithCString(NULL, bundle_id, kCFStringEncodingUTF8);
    } else {
        on_error(@"Error: you need to pass in the bundle id, (i.e. --bundle_id com.my.app)");
    }

    if (cf_uninstall_bundle_id == NULL) {
        on_error(@"Error: Unable to get bundle id from user command or package %@.\nUninstall failed.", [NSString stringWithUTF8String:app_path]);
    } else {
        connect_and_start_session(device);

        int code = AMDeviceSecureUninstallApplication(0, device, cf_uninstall_bundle_id, 0, NULL, 0);
        if (code == 0) {
            NSLogOut(@"[ OK ] Uninstalled package with bundle id %@", cf_uninstall_bundle_id);
        } else {
            on_error(@"[ ERROR ] Could not uninstall package with bundle id %@", cf_uninstall_bundle_id);
        }
        CFRelease(cf_uninstall_bundle_id);
        check_error(AMDeviceStopSession(device));
        check_error(AMDeviceDisconnect(device));
    }
}

void start_symbols_service_with_command(AMDeviceRef device, uint32_t command) {
    connect_and_start_session(device);
    check_error(AMDeviceSecureStartService(device, symbols_service_name,
                                           NULL, &dbgServiceConnection));

    uint32_t bytes_sent = AMDServiceConnectionSend(dbgServiceConnection, &command,
                                                    sizeof_uint32_t);
    if (bytes_sent != sizeof_uint32_t) {
        on_error(@"Sent %d bytes but was expecting %d.", bytes_sent, sizeof_uint32_t);
    }

    uint32_t response;
    uint32_t bytes_read = AMDServiceConnectionReceive(dbgServiceConnection,
                                                        &response, sizeof_uint32_t);
    if (bytes_read != sizeof_uint32_t) {
        on_error(@"Read %d bytes but was expecting %d.", bytes_read, sizeof_uint32_t);
    } else if (response != command) {
        on_error(@"Failed to get confirmation response for: %s", command);
    }
}

CFArrayRef get_dyld_file_paths(AMDeviceRef device) {
    start_symbols_service_with_command(device, symbols_file_paths_command);

    CFPropertyListFormat format;
    CFDictionaryRef dict = NULL;
    uint64_t bytes_read =
        AMDServiceConnectionReceiveMessage(dbgServiceConnection, &dict, &format);
    if (bytes_read == -1) {
        on_error(@"Received %d bytes after succesfully starting command %d.", bytes_read,
                 symbols_file_paths_command);
    }
    AMDeviceStopSession(device);
    AMDeviceDisconnect(device);

    CFStringRef files_key = CFSTR("files");
    if (!CFDictionaryContainsKey(dict, files_key)) {
        on_error(@"Incoming messasge did not contain key '%@', %@", files_key, dict);
    }
    return CFDictionaryGetValue(dict, files_key);
}

void write_dyld_file(CFStringRef dest, uint64_t file_size) {
    // Prepare the destination file by mapping it into memory.
    int fd = open(CFStringGetCStringPtr(dest, kCFStringEncodingUTF8),
                  O_RDWR | O_CREAT, 0644);
    if (fd == -1) {
        on_sys_error(@"Failed to open %@.", dest);
    }
    if (lseek(fd, file_size - 1, SEEK_SET) == -1) {
        on_sys_error(@"Failed to lseek to last byte.");
    }
    if (write(fd, "", 1) == -1) {
        on_sys_error(@"Failed to write to last byte.");
    }
    void *map = mmap(NULL, file_size, PROT_WRITE, MAP_SHARED, fd, 0);
    if (map == MAP_FAILED) {
        on_sys_error(@"Failed to mmap %@.", dest);
    }
    close(fd);

    // Read the file content packet by packet until we've copied the entire file
    // to disk.
    uint64_t total_bytes_read = 0;
    uint64_t last_time =
        get_current_time_in_milliseconds() / symbols_logging_interval_ms;
    while (total_bytes_read < file_size) {
        uint64_t bytes_remaining = file_size - total_bytes_read;
        // This fails for some reason if we try to download more than
        // INT_MAX bytes at a time.
        uint64_t bytes_to_download = MIN(bytes_remaining, INT_MAX - 1);
        uint64_t bytes_read = AMDServiceConnectionReceive(
            dbgServiceConnection, map + total_bytes_read, bytes_to_download);
        total_bytes_read += bytes_read;

        uint64_t current_time =
            get_current_time_in_milliseconds() / symbols_logging_interval_ms;
        // We can process several packets per second which would result
        // in spamming output so only log if any of the following are
        // true:
        //    - Running in verbose mode.
        //    - It's been at least a quarter second since the last log.
        //    - We finished processing the last packet.
        if (verbose || last_time != current_time || total_bytes_read == file_size) {
            last_time = current_time;
            int percent = (double)total_bytes_read / file_size * 100;
            NSLogOut(@"%llu/%llu (%d%%)", total_bytes_read, file_size, percent);
            NSLogJSON(@{@"Event": @"DyldCacheDownloadProgress",
                         @"BytesRead": @(total_bytes_read),
                         @"Percent": @(percent),
                      });
        }
    }

    munmap(map, file_size);
}

CFStringRef download_dyld_file(AMDeviceRef device, uint32_t dyld_index,
                        CFStringRef filepath) {
    start_symbols_service_with_command(device, symbols_download_file_command);

    uint32_t index = CFSwapInt32HostToBig(dyld_index);
    uint64_t bytes_sent =
        AMDServiceConnectionSend(dbgServiceConnection, &index, sizeof_uint32_t);
    if (bytes_sent != sizeof_uint32_t) {
        on_error(@"Sent %d bytes but was expecting %d.", bytes_sent, sizeof_uint32_t);
    }

    uint64_t file_size = 0;
    uint64_t bytes_read = AMDServiceConnectionReceive(dbgServiceConnection,
                                                    &file_size, sizeof(uint64_t));
    if (bytes_read != sizeof(uint64_t)) {
        on_error(@"Read %d bytes but was expecting %d.", bytes_read, sizeof(uint64_t));
    }
    file_size = CFSwapInt64BigToHost(file_size);

    CFStringRef download_path = CFStringCreateWithFormat(
        NULL, NULL, CFSTR("%s%@"), symbols_download_directory, filepath);
    mkdirp(
        ((__bridge NSString *)download_path).stringByDeletingLastPathComponent);
    NSLogOut(@"Downloading %@ to %@.", filepath, download_path);
    NSLogJSON(@{@"Event": @"DyldCacheDownload",
                 @"Source": (__bridge NSString *)filepath,
                 @"Destination": (__bridge NSString *)download_path,
                 @"Size": @(file_size),
              });

    write_dyld_file(download_path, file_size);

    AMDeviceStopSession(device);
    AMDeviceDisconnect(device);
    return download_path;
}

CFStringRef create_dsc_bundle_path_for_device(AMDeviceRef device) {
    CFStringRef xcode_dev_path = copy_xcode_dev_path();

    AMDeviceConnect(device);
    CFStringRef device_class = AMDeviceCopyValue(device, 0, CFSTR("DeviceClass"));
    AMDeviceDisconnect(device);

    CFStringRef platform_name;
    if (CFStringCompare(CFSTR("AppleTV"), device_class, 0) == kCFCompareEqualTo) {
        platform_name = CFSTR("AppleTVOS");
    } else if (CFStringCompare(CFSTR("Watch"), device_class, 0) ==
               kCFCompareEqualTo) {
        platform_name = CFSTR("WatchOS");
    } else {
        platform_name = CFSTR("iPhoneOS");
    }

    return CFStringCreateWithFormat(
        NULL, NULL,
        CFSTR("%@/Platforms/%@.platform/usr/lib/dsc_extractor.bundle"),
        xcode_dev_path, platform_name);
}

typedef int (*extractor_proc)(const char *shared_cache_file_path, const char *extraction_root_path,
                              void (^progress)(unsigned current, unsigned total));

void dyld_shared_cache_extract_dylibs(CFStringRef dsc_extractor_bundle_path,
                                      CFStringRef shared_cache_file_path,
                                      const char *extraction_root_path) {
    const char *dsc_extractor_bundle_path_ptr =
        CFStringGetCStringPtr(dsc_extractor_bundle_path, kCFStringEncodingUTF8);
    void *handle = dlopen(dsc_extractor_bundle_path_ptr, RTLD_LAZY);
    if (handle == NULL) {
        on_error(@"%s could not be loaded", dsc_extractor_bundle_path);
    }

    extractor_proc proc = (extractor_proc)dlsym(
        handle, "dyld_shared_cache_extract_dylibs_progress");
    if (proc == NULL) {
        on_error(
            @"%s did not have dyld_shared_cache_extract_dylibs_progress symbol",
            dsc_extractor_bundle_path);
    }

    const char *shared_cache_file_path_ptr =
        CFStringGetCStringPtr(shared_cache_file_path, kCFStringEncodingUTF8);
  
    NSLogJSON(@{@"Event": @"DyldCacheExtract",
                 @"Source": (__bridge NSString *)shared_cache_file_path,
                 @"Destination": @(extraction_root_path),
              });

    __block uint64_t last_time =
        get_current_time_in_milliseconds() / symbols_logging_interval_ms;
    __block unsigned files_extracted = 0;
    __block unsigned files_total = 0;
    int result =
        (*proc)(shared_cache_file_path_ptr, extraction_root_path,
                ^(unsigned c, unsigned total) {
              uint64_t current_time =
                  get_current_time_in_milliseconds() / symbols_logging_interval_ms;
              if (!verbose && last_time == current_time) return;

              last_time = current_time;
              files_extracted = c;
              files_total = total;
          
              int percent = (double)c / total * 100;
              NSLogOut(@"%d/%d (%d%%)", c, total, percent);
              NSLogJSON(@{@"Event": @"DyldCacheExtractProgress",
                           @"Extracted": @(c),
                           @"Total": @(total),
                           @"Percent": @(percent),
                        });
        });
    if (result == 0) {
        NSLogOut(@"Finished extracting %s.", shared_cache_file_path_ptr);
        files_extracted = files_total;
    } else {
        NSLogOut(@"Failed to extract %s, exit code %d.", shared_cache_file_path_ptr, result);
    }
    int percent = (double)files_extracted / files_total * 100;
    NSLogJSON(@{@"Event": @"DyldCacheExtractProgress",
                @"Code": @(result),
                @"Extracted": @(files_extracted),
                @"Total": @(files_total),
                @"Percent": @(percent),
              });
}

void download_device_symbols(AMDeviceRef device) {
    dbgServiceConnection = NULL;
    CFArrayRef files = get_dyld_file_paths(device);
    CFIndex files_count = CFArrayGetCount(files);
    NSLogOut(@"Downloading symbols files: %@", files);
    NSLogJSON(@{@"Event": @"SymbolsDownload",
                 @"Files": (__bridge NSArray *)files,
              });
    CFStringRef dsc_extractor_bundle = create_dsc_bundle_path_for_device(device);

    for (uint32_t i = 0; i < files_count; ++i) {
        CFStringRef filepath = (CFStringRef)CFArrayGetValueAtIndex(files, i);
        CFStringRef download_path = download_dyld_file(device, i, filepath);
        dyld_shared_cache_extract_dylibs(dsc_extractor_bundle, download_path,
                                             symbols_download_directory);
        CFRelease(download_path);
    }

    CFRelease(dsc_extractor_bundle);
}

void handle_device(AMDeviceRef device) {
    NSLogVerbose(@"Already found device? %d", found_device);

    CFStringRef device_full_name = get_device_full_name(device),
                device_interface_name = get_device_interface_name(device);

    if (detect_only) {
        if (_json_output) {
            NSLogJSON(@{@"Event": @"DeviceDetected",
                        @"Device": get_device_json_dict(device)
                        });
        } else {
            NSLogOut(@"[....] Found %@ connected through %@.", device_full_name, device_interface_name);
        }
        found_device = true;
        return;
    }
    if (found_device)
    {
        NSLogVerbose(@"Skipping %@.", device_full_name);
        return;
    }
    CFStringRef found_device_id = CFAutorelease(AMDeviceCopyDeviceIdentifier(device));
    if (device_id != NULL) {
        CFStringRef deviceCFSTR = CFAutorelease(CFStringCreateWithCString(NULL, device_id, kCFStringEncodingUTF8));
        if (CFStringCompare(deviceCFSTR, found_device_id, kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            found_device = true;
        } else {
            NSLogVerbose(@"Skipping %@.", device_full_name);
            return;
        }
    } else {
        // Use the first device we find if a device_id wasn't specified.
        device_id = strdup(CFStringGetCStringPtr(found_device_id, kCFStringEncodingUTF8));
        found_device = true;
    }

    NSLogOut(@"[....] Using %@.", device_full_name);

    if (command_only) {
        if (strcmp("list", command) == 0) {
            list_files(device);
        } else if (strcmp("upload", command) == 0) {
            upload_file(device);
        } else if (strcmp("download", command) == 0) {
            download_tree(device);
        } else if (strcmp("mkdir", command) == 0) {
            make_directory(device);
        } else if (strcmp("rm", command) == 0) {
            remove_path(device);
        } else if (strcmp("rmtree", command) == 0) {
            rmtree(device);
        } else if (strcmp("exists", command) == 0) {
            exit(app_exists(device));
        } else if (strcmp("uninstall_only", command) == 0) {
            uninstall_app(device);
        } else if (strcmp("list_bundle_id", command) == 0) {
            list_bundle_id(device);
        } else if (strcmp("get_battery_level", command) == 0) {
            get_battery_level(device);
        } else if (strcmp("symbols", command) == 0) {
            download_device_symbols(device);
        } else if (strcmp("list_profiles", command) == 0) {
            list_provisioning_profiles(device);
        } else if (strcmp("install_profile", command) == 0) {
            install_provisioning_profile(device);
        } else if (strcmp("uninstall_profile", command) == 0) {
            uninstall_provisioning_profile(device);
        } else if (strcmp("download_profile", command) == 0) {
            download_provisioning_profile(device);
        }
        exit(0);
    }

    if (debugserver_only && app_path == NULL) {
        launch_debugserver_only(device, NULL);
        return;
    }

    CFRetain(device); // don't know if this is necessary?

    CFStringRef path = CFStringCreateWithCString(NULL, app_path, kCFStringEncodingUTF8);
    CFURLRef relative_url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, false);
    CFURLRef url = CFURLCopyAbsoluteURL(relative_url);

    CFRelease(relative_url);

    if (uninstall) {
        NSLogOut(@"------ Uninstall phase ------");

        //Do we already have the bundle_id passed in via the command line? if so, use it.
        CFStringRef cf_uninstall_bundle_id = NULL;
        if (bundle_id != NULL)
        {
            cf_uninstall_bundle_id = CFStringCreateWithCString(NULL, bundle_id, kCFStringEncodingUTF8);
        } else {
            cf_uninstall_bundle_id = copy_bundle_id(url);
        }

        if (cf_uninstall_bundle_id == NULL) {
            on_error(@"Error: Unable to get bundle id from user command or package %@.\nUninstall failed.", [NSString stringWithUTF8String:app_path]);
        } else {
            connect_and_start_session(device);

            int code = AMDeviceSecureUninstallApplication(0, device, cf_uninstall_bundle_id, 0, NULL, 0);
            if (code == 0) {
                NSLogOut(@"[ OK ] Uninstalled package with bundle id %@", cf_uninstall_bundle_id);
            } else {
                on_error(@"[ ERROR ] Could not uninstall package with bundle id %@", cf_uninstall_bundle_id);
            }
            CFRelease(cf_uninstall_bundle_id);
            check_error(AMDeviceStopSession(device));
            check_error(AMDeviceDisconnect(device));
        }
    }

    if(install) {
        NSLogOut(@"------ Install phase ------");
        NSLogOut(@"[  0%%] Found %@ connected through %@, beginning install", device_full_name, device_interface_name);

        CFStringRef install_bundle_id = NULL;
        if (bundle_id != NULL) {
          install_bundle_id = CFStringCreateWithCString(NULL, bundle_id, kCFStringEncodingUTF8);
        } else {
          CFStringRef extracted_bundle_id = copy_bundle_id(url);
          if (extracted_bundle_id == NULL) {
            on_error(@"[ ERROR] Could not determine bundle id.");
          }
          install_bundle_id = extracted_bundle_id;
        }

        CFDictionaryRef options;
        if (app_deltas == NULL) { // standard install
          CFStringRef keys[] = { CFSTR("PackageType") };
          CFStringRef values[] = { CFSTR("Developer") };
          options = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
          check_error(AMDeviceSecureTransferPath(0, device, url, options, transfer_callback, 0));

          connect_and_start_session(device);
          check_error(AMDeviceSecureInstallApplication(0, device, url, options, install_callback, 0));
          check_error(AMDeviceStopSession(device));
          check_error(AMDeviceDisconnect(device));
        } else { // incremental install
          CFStringRef deltas_path =
            CFStringCreateWithCString(NULL, app_deltas, kCFStringEncodingUTF8);
          CFURLRef deltas_relative_url =
            CFURLCreateWithFileSystemPath(NULL, deltas_path, kCFURLPOSIXPathStyle, false);
          CFURLRef app_deltas_url = CFURLCopyAbsoluteURL(deltas_relative_url);
          CFStringRef prefer_wifi = no_wifi ? CFSTR("0") : CFSTR("1");

          // These values were determined by inspecting Xcode 11.1 logs with the Console app.
          CFStringRef keys[] = {
            CFSTR("CFBundleIdentifier"),
            CFSTR("CloseOnInvalidate"),
            CFSTR("InvalidateOnDetach"),
            CFSTR("IsUserInitiated"),
            CFSTR("PackageType"),
            CFSTR("PreferWifi"),
            CFSTR("ShadowParentKey"),
          };
          CFStringRef values[] = {
            install_bundle_id,
            CFSTR("1"),
            CFSTR("1"),
            CFSTR("1"),
            CFSTR("Developer"),
            prefer_wifi,
            (CFStringRef)app_deltas_url,
          };

          CFIndex size = sizeof(keys)/sizeof(CFStringRef);
          options = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, size, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

          // Incremental installs should be done without a session started because of timeouts.
          check_error(AMDeviceSecureInstallApplicationBundle(device, url, options, incremental_install_callback, 0));
          CFRelease(deltas_path);
          CFRelease(deltas_relative_url);
          CFRelease(app_deltas_url);
          free(app_deltas);
          app_deltas = NULL;
        }

        CFRelease(options);

        connect_and_start_session(device);
        CFURLRef device_app_url = copy_device_app_url(device, install_bundle_id);
        check_error(AMDeviceStopSession(device));
        check_error(AMDeviceDisconnect(device));
        CFStringRef device_app_path = CFURLCopyFileSystemPath(device_app_url, kCFURLPOSIXPathStyle);

        NSLogOut(@"[100%%] Installed package %@", [NSString stringWithUTF8String:app_path]);
        NSLogVerbose(@"App path: %@", device_app_path);
        NSLogJSON(@{@"Event": @"BundleInstall",
                    @"OverallPercent": @(100),
                    @"Percent": @(100),
                    @"Status": @"Complete",
                    @"Path": (__bridge NSString *)device_app_path
                    });

      CFRelease(device_app_url);
      CFRelease(install_bundle_id);
      CFRelease(device_app_path);
    }
    CFRelease(path);

    if (!debug)
        exit(0); // no debug phase

    if (justlaunch) {
        launch_debugger_and_exit(device, url);
    } else if (debugserver_only) {
        launch_debugserver_only(device, url);
    } else {
        launch_debugger(device, url);
    }
}

void device_callback(struct am_device_notification_callback_info *info, void *arg) {
    switch (info->msg) {
        case ADNCI_MSG_CONNECTED:
        {
            int itype = AMDeviceGetInterfaceType(info->dev);
            if (no_wifi &&  (itype == 2 || ( itype == 3 && get_companion_interface_type(info->dev) == 2)))
            {
                NSLogVerbose(@"Skipping wifi device (type: %d)", itype);
            }
            else
            {
                NSLogVerbose(@"Handling device type: %d", itype);
                handle_device(info->dev);
            }
            break;
        }
        case ADNCI_MSG_DISCONNECTED:
        {
            CFStringRef device_interface_name = get_device_interface_name(info->dev);
            CFStringRef device_uuid = AMDeviceCopyDeviceIdentifier(info->dev);
            NSLogVerbose(@"[....] Disconnected %@ from %@.", device_uuid, device_interface_name);
            if (detect_only && _json_output) {
                NSLogJSON(@{@"Event": @"DeviceDisconnected",
                            @"Device": get_device_json_dict(info->dev)
                            });
            }
            CFRelease(device_uuid);
            break;
        }
        default:
            break;
    }
}

void timeout_callback(CFRunLoopTimerRef timer, void *info) {
    if (found_device && (!detect_only)) {
        // Don't need to exit in the justlaunch mode
        if (justlaunch)
            return;

        // App running for too long
        NSLogOut(@"[ !! ] App is running for too long");
        exit(exitcode_timeout);
        return;
    } else if ((!found_device) && (!detect_only))  {
        on_error(@"Timed out waiting for device.");
    }
    else
    {
        // Device detection timeout
        if (!debug) {
            NSLogOut(@"[....] No more devices found.");
        }

        if (detect_only && !found_device) {
            exit(exitcode_error);
            return;
        } else {
            int mypid = getpid();
            if ((parent != 0) && (parent == mypid) && (child != 0))
            {
                NSLogVerbose(@"Timeout. Killing child (%d) tree.", child);
                kill_ptree(child, SIGHUP);
            }
        }
        exit(0);
    }
}

void usage(const char* app) {
    NSLog(
        @"Usage: %@ [OPTION]...\n"
        @"  -d, --debug                  launch the app in lldb after installation\n"
        @"  -i, --id <device_id>         the id of the device to connect to\n"
        @"  -c, --detect                 list all connected devices\n"
        @"  -b, --bundle <bundle.app>    the path to the app bundle to be installed\n"
        @"  -a, --args <args>            command line arguments to pass to the app when launching it\n"
        @"  -s, --envs <envs>            environment variables, space separated key-value pairs, to pass to the app when launching it\n"
        @"  -t, --timeout <timeout>      number of seconds to wait for a device to be connected\n"
        @"  -u, --unbuffered             don't buffer stdout\n"
        @"  -n, --nostart                do not start the app when debugging\n"
        @"  -N, --nolldb                 start debugserver only. do not run lldb. Can not be used with args or envs options\n"
        @"  -I, --noninteractive         start in non interactive mode (quit when app crashes or exits)\n"
        @"  -L, --justlaunch             just launch the app and exit lldb\n"
        @"  -v, --verbose                enable verbose output\n"
        @"  -m, --noinstall              directly start debugging without app install (-d not required)\n"
        @"  -A, --app_deltas             incremental install. must specify a directory to store app deltas to determine what needs to be installed\n"
        @"  -p, --port <number>          port used for device, default: dynamic\n"
        @"  -r, --uninstall              uninstall the app before install (do not use with -m; app cache and data are cleared) \n"
        @"  -9, --uninstall_only         uninstall the app ONLY. Use only with -1 <bundle_id> \n"
        @"  -1, --bundle_id <bundle id>  specify bundle id for list and upload\n"
        @"  -l, --list[=<dir>]           list all app files or the specified directory\n"
        @"  -o, --upload <file>          upload file\n"
        @"  -w, --download[=<path>]      download app tree or the specified file/directory\n"
        @"  -2, --to <target pathname>   use together with up/download file/tree. specify target\n"
        @"  -D, --mkdir <dir>            make directory on device\n"
        @"  -R, --rm <path>              remove file or directory on device (directories must be empty)\n"
        @"  -X, --rmtree <path>          remove directory and all contained files recursively on device\n"
        @"  -V, --version                print the executable version \n"
        @"  -e, --exists                 check if the app with given bundle_id is installed or not \n"
        @"  -B, --list_bundle_id         list bundle_id \n"
        @"  -W, --no-wifi                ignore wifi devices\n"
        @"  -C, --get_battery_level      get battery current capacity \n"
        @"  -O, --output <file>          write stdout to this file\n"
        @"  -E, --error_output <file>    write stderr to this file\n"
        @"  --detect_deadlocks <sec>     start printing backtraces for all threads periodically after specific amount of seconds\n"
        @"  -f, --file_system            specify file system for mkdir / list / upload / download / rm\n"
        @"  -F, --non-recursively        specify non-recursively walk directory\n"
        @"  -S, --symbols                download OS symbols. must specify a directory to store the downloaded symbols\n"
        @"  -j, --json                   format output as JSON\n"
        @"  -k, --key                    keys for the properties of the bundle. Joined by ',' and used only with -B <list_bundle_id> and -j <json> \n"
        @"  --custom-script <script>     path to custom python script to execute in lldb\n"
        @"  --custom-command <command>   specify additional lldb commands to execute\n"
        @"  --faster-path-search         use alternative logic to find the device support paths faster\n"
        @"  -P, --list_profiles          list all provisioning profiles on device\n"
        @"  --profile-uuid <uuid>        the UUID of the provisioning profile to target, use with other profile commands\n"
        @"  --profile-download <path>    download a provisioning profile (requires --profile-uuid)\n"
        @"  --profile-install <file>     install a provisioning profile\n"
        @"  --profile-uninstall          uninstall a provisioning profile (requires --profile-uuid <UUID>)\n",
        [NSString stringWithUTF8String:app]);
}

void show_version(void) {
    NSLogOut(@"%@", @
#include "version.h"
             );
}

int main(int argc, char *argv[]) {

    // create a UUID for tmp purposes
    CFUUIDRef uuid = CFUUIDCreate(NULL);
    CFStringRef str = CFUUIDCreateString(NULL, uuid);
    CFRelease(uuid);
    tmpUUID = [(NSString*)str autorelease];

    static struct option longopts[] = {
        { "debug", no_argument, NULL, 'd' },
        { "id", required_argument, NULL, 'i' },
        { "bundle", required_argument, NULL, 'b' },
        { "args", required_argument, NULL, 'a' },
        { "envs", required_argument, NULL, 's' },
        { "verbose", no_argument, NULL, 'v' },
        { "timeout", required_argument, NULL, 't' },
        { "unbuffered", no_argument, NULL, 'u' },
        { "nostart", no_argument, NULL, 'n' },
        { "nolldb", no_argument, NULL, 'N' },
        { "noninteractive", no_argument, NULL, 'I' },
        { "justlaunch", no_argument, NULL, 'L' },
        { "detect", no_argument, NULL, 'c' },
        { "version", no_argument, NULL, 'V' },
        { "noinstall", no_argument, NULL, 'm' },
        { "port", required_argument, NULL, 'p' },
        { "uninstall", no_argument, NULL, 'r' },
        { "uninstall_only", no_argument, NULL, '9'},
        { "list", optional_argument, NULL, 'l' },
        { "bundle_id", required_argument, NULL, '1'},
        { "upload", required_argument, NULL, 'o'},
        { "download", optional_argument, NULL, 'w'},
        { "to", required_argument, NULL, '2'},
        { "mkdir", required_argument, NULL, 'D'},
        { "rm", required_argument, NULL, 'R'},
        { "rmtree",required_argument, NULL, 'X'},
        { "exists", no_argument, NULL, 'e'},
        { "list_bundle_id", no_argument, NULL, 'B'},
        { "no-wifi", no_argument, NULL, 'W'},
        { "get_battery_level", no_argument, NULL, 'C'},
        { "output", required_argument, NULL, 'O' },
        { "error_output", required_argument, NULL, 'E' },
        { "detect_deadlocks", required_argument, NULL, 1000 },
        { "json", no_argument, NULL, 'j'},
        { "app_deltas", required_argument, NULL, 'A'},
        { "file_system", no_argument, NULL, 'f'},
        { "non-recursively", no_argument, NULL, 'F'},
        { "key", optional_argument, NULL, 'k' },
        { "symbols", required_argument, NULL, 'S' },
        { "list_profiles", no_argument, NULL, 'P' },
        { "custom-script", required_argument, NULL, 1001},
        { "custom-command", required_argument, NULL, 1002},
        { "faster-path-search", no_argument, NULL, 1003},
        { "profile-install", required_argument, NULL, 1004},
        { "profile-uninstall", no_argument, NULL, 1005},
        { "profile-download", required_argument, NULL, 1006},
        { "profile-uuid", required_argument, NULL, 1007},
        { NULL, 0, NULL, 0 },
    };
    int ch;

    while ((ch = getopt_long(argc, argv, "VmcdvunrILefFD:R:X:i:b:a:t:p:1:2:o:l:w:9BWjNs:OE:CA:k:S:P", longopts, NULL)) != -1)
    {
        switch (ch) {
        case 'm':
            install = false;
            debug = true;
            break;
        case 'd':
            debug = true;
            break;
        case 'i':
            device_id = optarg;
            break;
        case 'b':
            app_path = optarg;
            break;
        case 'a':
            args = optarg;
            break;
        case 's':
            envs = optarg;
            break;
        case 'S':
            symbols_download_directory = optarg;
            command = "symbols";
            command_only = true;
            break;
        case 'v':
            verbose = true;
            break;
        case 't':
            _timeout = atoi(optarg);
            break;
        case 'u':
            unbuffered = true;
            break;
        case 'n':
            nostart = true;
            break;
        case 'N':
            debugserver_only = true;
            debug = true;
            break;
        case 'I':
            interactive = false;
            debug = true;
            break;
        case 'L':
            interactive = false;
            justlaunch = true;
            debug = true;
            break;
        case 'c':
            detect_only = true;
            debug = true;
            break;
        case 'V':
            show_version();
            return 0;
        case 'p':
            port = atoi(optarg);
            break;
        case 'r':
            uninstall = true;
            break;
        case '9':
            command_only = true;
            command = "uninstall_only";
            break;
        case '1':
            bundle_id = optarg;
            break;
        case '2':
            target_filename = optarg;
            break;
        case 'o':
            command_only = true;
            upload_pathname = optarg;
            command = "upload";
            break;
        case 'l':
            command_only = true;
            command = "list";
            list_root = optarg;
            break;
        case 'w':
            command_only = true;
            command = "download";
            list_root = optarg;
            break;
        case 'D':
            command_only = true;
            target_filename = optarg;
            command = "mkdir";
            break;
        case 'R':
            command_only = true;
            target_filename = optarg;
            command = "rm";
            break;
        case 'X':
            command_only = true;
            target_filename = optarg;
            command = "rmtree";
            break;
        case 'e':
            command_only = true;
            command = "exists";
            break;
        case 'B':
            command_only = true;
            command = "list_bundle_id";
            break;
        case 'W':
            no_wifi = true;
            break;
        case 'C':
            command_only = true;
            command = "get_battery_level";
            break;
        case 'O':
            output_path = optarg;
            break;
        case 'E':
            error_path = optarg;
            break;
        case 1000:
            _detectDeadlockTimeout = atoi(optarg);
            break;
        case 'j':
            _json_output = true;
            break;
        case 'A':
            app_deltas = resolve_path(optarg);
            break;
        case 'f':
            file_system = true;
            break;
        case 'F':
            non_recursively = true;
            break;
        case 1001:
            custom_script_path = optarg;
            break;
        case 1002:
            if (custom_commands == nil)
            {
                custom_commands = [[NSMutableString alloc] init];
            }
            [custom_commands appendFormat:@"%s\n", optarg];
            break;
        case 1003:
            faster_path_search = true;
            break;
        case 1004:
            command_only = true;
            command = "install_profile";
            profile_path = optarg;
            break;
        case 1005:
            command_only = true;
            command = "uninstall_profile";
            break;
        case 1006:
            command_only = true;
            command = "download_profile";
            profile_path = optarg;
            break;
        case 1007:
            profile_uuid = optarg;
            break;
        case 'P':
            command_only = true;
            command = "list_profiles";
            break;
        case 'k':
            if (!keys) keys = [[NSMutableArray alloc] init];
            [keys addObject: [NSString stringWithUTF8String:optarg]];
            break;
        default:
            usage(argv[0]);
            return exitcode_error;
        }
    }
    
    if (debugserver_only && (args || envs)) {
        usage(argv[0]);
        on_error(@"The --args and --envs options can not be combined with --nolldb.");
    }

    if (!app_path && !detect_only && !debugserver_only && !command_only) {
        usage(argv[0]);
        on_error(@"One of -[b|c|o|l|w|D|N|R|X|e|B|C|S|9] is required to proceed!");
    }

    if (unbuffered) {
        setbuf(stdout, NULL);
        setbuf(stderr, NULL);
    }

    if (detect_only && _timeout == 0) {
        _timeout = 5;
    }

    if (app_path) {
        if (access(app_path, F_OK) != 0) {
            on_sys_error(@"Can't access app path '%@'", [NSString stringWithUTF8String:app_path]);
        }
    }

    AMDSetLogLevel(5); // otherwise syslog gets flooded with crap
    if (_timeout > 0)
    {
        CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + _timeout, 0, 0, 0, timeout_callback, NULL);
        CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);
        NSLogOut(@"[....] Waiting up to %d seconds for iOS device to be connected", _timeout);
    }
    else
    {
        NSLogOut(@"[....] Waiting for iOS device to be connected");
    }


    CFStringRef keys[] = {
        CFSTR("NotificationOptionSearchForPairedDevices"),
    };
    const void* values[] = {
        kCFBooleanTrue,
    };
    CFDictionaryRef options = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, values, 1, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    AMDeviceNotificationSubscribeWithOptions(&device_callback, 0, 0, NULL, &notify, options);
    CFRunLoopRun();
}
