/*
 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#import <Cocoa/Cocoa.h>
#import <CoreFoundation/CoreFoundation.h>

// We need to weak-import posix_spawn and friends as they're not available on Tiger.
// The BSD-level system headers do not have availability macros, so we redeclare the
// functions ourselves with the "weak" attribute.

#define WEAK_IMPORT __attribute__((weak))

#define POSIX_SPAWN_SETEXEC 0x0040
typedef void *posix_spawnattr_t;
typedef void *posix_spawn_file_actions_t;
int posix_spawnattr_init(posix_spawnattr_t *) WEAK_IMPORT;
int posix_spawn(pid_t * __restrict, const char * __restrict, const posix_spawn_file_actions_t *, const posix_spawnattr_t * __restrict, char *const __argv[ __restrict], char *const __envp[ __restrict]) WEAK_IMPORT;
int posix_spawnattr_setbinpref_np(posix_spawnattr_t * __restrict, size_t, cpu_type_t *__restrict, size_t *__restrict) WEAK_IMPORT;
int posix_spawnattr_setflags(posix_spawnattr_t *, short) WEAK_IMPORT;


static void displayErrorAndQuit(NSString *title, NSString *message)
{
    NSApplicationLoad();
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    NSRunCriticalAlertPanel(title, @"%@", @"Quit", nil, nil, message);
#pragma clang diagnostic pop
    exit(0);
}

static int getLastVersionShown()
{
    [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:@"-1" forKey:@"StartPageShownInVersion"]];
    return [[NSUserDefaults standardUserDefaults] integerForKey:@"StartPageShownInVersion"];
}

static void saveLastVersionShown(int lastVersion)
{
    [[NSUserDefaults standardUserDefaults] setInteger:lastVersion forKey:@"StartPageShownInVersion"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

static NSString *getPathForStartPage()
{
    return [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"start.html"];
}

static int getCurrentVersion()
{
    return [[[[NSBundle mainBundle] infoDictionary] valueForKey:(NSString *)kCFBundleVersionKey] intValue];
}

static int getShowStartPageVersion()
{
    return getCurrentVersion() + 1;
}

static BOOL startPageDisabled()
{
    return [[NSUserDefaults standardUserDefaults] boolForKey:@"StartPageDisabled"];
}

static void addStartPageToArgumentsIfNeeded(NSMutableArray *arguments)
{
    if (startPageDisabled())
        return;

    if (getLastVersionShown() < getShowStartPageVersion()) {
        saveLastVersionShown(getCurrentVersion());
        NSString *startPagePath = getPathForStartPage();
        if (startPagePath)
            [arguments addObject:startPagePath];
    }
}

static cpu_type_t preferredArchitecture()
{
#if defined(__ppc__)
    return CPU_TYPE_POWERPC;
#elif defined(__LP64__)
    return CPU_TYPE_X86_64;
#else
    return CPU_TYPE_X86;
#endif
}

static void myExecve(NSString *executable, NSArray *args, NSDictionary *environment)
{
    char **argv = (char **)calloc(sizeof(char *), [args count] + 1);
    char **env = (char **)calloc(sizeof(char *), [environment count] + 1);

    NSEnumerator *e = [args objectEnumerator];
    NSString *s;
    int i = 0;
    while ((s = [e nextObject]))
        argv[i++] = (char *) [s UTF8String];

    e = [environment keyEnumerator];
    i = 0;
    while ((s = [e nextObject]))
        env[i++] = (char *) [[NSString stringWithFormat:@"%@=%@", s, [environment objectForKey:s]] UTF8String];

    if (posix_spawnattr_init && posix_spawn && posix_spawnattr_setbinpref_np && posix_spawnattr_setflags) {
        posix_spawnattr_t attr;
        posix_spawnattr_init(&attr);
        cpu_type_t architecturePreference[] = { preferredArchitecture(), CPU_TYPE_X86 };
        posix_spawnattr_setbinpref_np(&attr, 2, architecturePreference, 0);
        short flags = POSIX_SPAWN_SETEXEC;
        posix_spawnattr_setflags(&attr, flags);
        posix_spawn(NULL, [executable fileSystemRepresentation], NULL, &attr, argv, env);
    } else
        execve([executable fileSystemRepresentation], argv, env);
}

static NSBundle *locateSafariBundle()
{
    NSArray *applicationDirectories = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSAllDomainsMask, YES);
    NSEnumerator *e = [applicationDirectories objectEnumerator];
    NSString *applicationDirectory;
    while ((applicationDirectory = [e nextObject])) {
        NSString *possibleSafariPath = [applicationDirectory stringByAppendingPathComponent:@"Safari.app"];
        NSBundle *possibleSafariBundle = [NSBundle bundleWithPath:possibleSafariPath];
        if ([[possibleSafariBundle bundleIdentifier] isEqualToString:@"com.apple.Safari"])
            return possibleSafariBundle;
    }

    CFURLRef safariURL = nil;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    OSStatus err = LSFindApplicationForInfo(kLSUnknownCreator, CFSTR("com.apple.Safari"), nil, nil, &safariURL);
#pragma clang diagnostic pop
    if (err != noErr)
        displayErrorAndQuit(@"Unable to locate Safari", @"Nightly builds of WebKit require Safari to run.  Please check that it is available and then try again.");

    NSBundle *safariBundle = [NSBundle bundleWithPath:[(NSURL *)safariURL path]];
    CFRelease(safariURL);
    return safariBundle;
}

static NSString *determineExecutablePath(NSBundle *bundle)
{
    NSString *safariExecutablePath = [bundle executablePath];

    NSString *safariForWebKitDevelopmentExecutablePath = [bundle pathForAuxiliaryExecutable:@"SafariForWebKitDevelopment"];
    if (![[NSFileManager defaultManager] fileExistsAtPath:safariForWebKitDevelopmentExecutablePath])
        return safariExecutablePath;

    SecStaticCodeRef staticCode;
    if (SecStaticCodeCreateWithPath((CFURLRef)[bundle executableURL], kSecCSDefaultFlags, &staticCode) != noErr)
        return [bundle executablePath];

    NSDictionary *codeInformation;
    if (SecCodeCopySigningInformation(staticCode, kSecCSRequirementInformation, (CFDictionaryRef*)&codeInformation) != noErr) {
        CFRelease(staticCode);
        return safariExecutablePath;
    }
    CFRelease(staticCode);
    [codeInformation autorelease];

    if ([codeInformation objectForKey:(id)kSecCodeInfoEntitlements])
        return safariForWebKitDevelopmentExecutablePath;

    return safariExecutablePath;
}

static NSString *currentMacOSXVersion()
{
    // Can't use -[NSProcessInfo operatingSystemVersionString] because it has too much stuff we don't want.
    NSString *systemLibraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSSystemDomainMask, YES) objectAtIndex:0];
    NSString *systemVersionPlistPath = [systemLibraryPath stringByAppendingPathComponent:@"CoreServices/SystemVersion.plist"];
    NSDictionary *systemVersionInfo = [NSDictionary dictionaryWithContentsOfFile:systemVersionPlistPath];
    return [systemVersionInfo objectForKey:@"ProductVersion"];
}

static NSString *currentMacOSXMajorVersion()
{
    NSArray *allComponents = [currentMacOSXVersion() componentsSeparatedByString:@"."];
    NSArray *majorAndMinorComponents = [allComponents objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)]];
    return [majorAndMinorComponents componentsJoinedByString:@"."];
}

static NSString *fallbackMacOSXVersion(NSString *systemVersion)
{
    NSDictionary *fallbackVersionMap = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"FallbackSystemVersions"];
    if (!fallbackVersionMap)
        return nil;
    NSString *fallbackSystemVersion = [fallbackVersionMap objectForKey:systemVersion];
    if (!fallbackSystemVersion || ![fallbackSystemVersion isKindOfClass:[NSString class]])
        return nil;
    return fallbackSystemVersion;
}

static BOOL checkFrameworkPath(NSString *frameworkPath)
{
    BOOL isDirectory = NO;
    return [[NSFileManager defaultManager] fileExistsAtPath:frameworkPath isDirectory:&isDirectory] && isDirectory;
}

static BOOL checkSafariVersion(NSBundle *safariBundle)
{
    NSString *safariBundleVersion = [[safariBundle infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey];
    NSString *majorComponent = [[safariBundleVersion componentsSeparatedByString:@"."] objectAtIndex:0];
    NSString *majorVersion = [majorComponent substringFromIndex:[majorComponent length] - 3];
    return [majorVersion intValue] >= 530;
}

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

    NSString *systemVersion = currentMacOSXMajorVersion();
    NSString *frameworkPath = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:systemVersion];

    BOOL frameworkPathIsUsable = checkFrameworkPath(frameworkPath);

    if (!frameworkPathIsUsable) {
        NSString *fallbackSystemVersion = fallbackMacOSXVersion(systemVersion);
        if (fallbackSystemVersion) {
            frameworkPath = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:fallbackSystemVersion];
            frameworkPathIsUsable = checkFrameworkPath(frameworkPath);
        }
    }

    if (!frameworkPathIsUsable)
        displayErrorAndQuit([NSString stringWithFormat:@"OS X %@ is not supported", systemVersion],
                            [NSString stringWithFormat:@"Nightly builds of WebKit are not supported on OS X %@ at this time.", systemVersion]);

    NSString *pathToEnablerLib = [[NSBundle mainBundle] pathForResource:@"WebKitNightlyEnabler" ofType:@"dylib"];
    NSString *dyldInsertLibraries = pathToEnablerLib;
    NSString *pathToASanCrashReporterLib = [[NSBundle mainBundle] pathForResource:@"libasancrashreporter" ofType:@"dylib"];
    if (pathToASanCrashReporterLib)
        dyldInsertLibraries = [@[ pathToASanCrashReporterLib, pathToEnablerLib ] componentsJoinedByString:@":"];

    NSBundle *safariBundle = locateSafariBundle();
    NSString *executablePath = determineExecutablePath(safariBundle);

    if (!checkSafariVersion(safariBundle)) {
        NSString *safariVersion = [[safariBundle localizedInfoDictionary] objectForKey:@"CFBundleShortVersionString"];
        displayErrorAndQuit([NSString stringWithFormat:@"Safari %@ is not supported", safariVersion],
                            [NSString stringWithFormat:@"Nightly builds of WebKit are not supported with Safari %@ at this time. Please update to a newer version of Safari.", safariVersion]);
    }

    if ([frameworkPath rangeOfString:@":"].location != NSNotFound ||
        [pathToEnablerLib rangeOfString:@":"].location != NSNotFound)
        displayErrorAndQuit(@"Unable to launch Safari",
                            @"WebKit is located at a path containing an unsupported character.  Please move WebKit to a different location and try again.");

    NSMutableArray *arguments = [NSMutableArray arrayWithObject:executablePath];
    NSMutableDictionary *environment = [[[NSDictionary dictionaryWithObjectsAndKeys:frameworkPath, @"DYLD_FRAMEWORK_PATH", @"YES", @"WEBKIT_UNSET_DYLD_FRAMEWORK_PATH",
                                                                                    dyldInsertLibraries, @"DYLD_INSERT_LIBRARIES", [[NSBundle mainBundle] executablePath], @"WebKitAppPath", nil] mutableCopy] autorelease];
    [environment addEntriesFromDictionary:[[NSProcessInfo processInfo] environment]];
    addStartPageToArgumentsIfNeeded(arguments);

    while (*++argv)
        [arguments addObject:[NSString stringWithUTF8String:*argv]];

    myExecve(executablePath, arguments, environment);

    char *error = strerror(errno);
    NSString *errorMessage = [NSString stringWithFormat:@"Launching Safari at %@ failed with the error '%s' (%d)", [safariBundle bundlePath], error, errno];
    displayErrorAndQuit(@"Unable to launch Safari", errorMessage);

    [pool release];
    return 0;
}
