//
//  pithos_macosAppDelegate.m
//  pithos-macos
//
// Copyright 2011 GRNET S.A. 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.
// 
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``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 GRNET S.A OR
// 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.
// 
// The views and conclusions contained in the software and
// documentation are those of the authors and should not be
// interpreted as representing official policies, either expressed
// or implied, of GRNET S.A.

#import "pithos_macosAppDelegate.h"
#import "PithosBrowserController.h"
#import "PithosPreferencesController.h"
#import "ASIPithosRequest.h"
#import "ASIDownloadCache.h"

@implementation pithos_macosAppDelegate
@synthesize storageURLPrefix, publicURLPrefix;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // XXX hardcoded for now
    storageURLPrefix = @"https://pithos.dev.grnet.gr/v1";
    publicURLPrefix = @"https://pithos.dev.grnet.gr";
    
    [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self 
                                                       andSelector:@selector(handleAppleEvent:withReplyEvent:) 
                                                     forEventClass:kInternetEventClass 
                                                        andEventID:kAEGetURL];
    [self showPithosBrowser:self];
    
    [self authenticateWithAuthUser:[[userDefaultsController values] valueForKey:@"authUser"] 
                         authToken:[[userDefaultsController values] valueForKey:@"authToken"]];
}

// Based on: http://cocoatutorial.grapewave.com/2010/01/creating-a-status-bar-application/
// and: http://www.cocoadev.com/index.pl?ThumbnailImages
- (void)awakeFromNib {
    NSImage *sourceImage = [NSImage imageNamed:NSImageNameFolder];
    
    NSImage *smallImage = [[[NSImage alloc] initWithSize:NSMakeSize(18, 18)] autorelease];
    [smallImage lockFocus];
    [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
    [sourceImage setSize:NSMakeSize(18, 18)];
    [sourceImage compositeToPoint:NSZeroPoint operation:NSCompositeCopy];
    [smallImage unlockFocus];
    
    statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
    [statusItem setMenu:statusMenu];
    [statusItem setImage:sourceImage];
    [statusItem setHighlightMode:YES];
}

- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent {
    NSURL *url = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]];
    NSString *host = [url host];
	NSString *query = [url query];
    NSLog(@"host : '%@', query: '%@'", host, query);
    NSProcessInfo *processInfo = [NSProcessInfo processInfo];
    if ([host isEqualToString:[NSString stringWithFormat:@"%@_%d", [processInfo processName], [processInfo processIdentifier]]] && query) {
        // user=
        NSString *authUser;
        NSRange userRange = [query rangeOfString:@"user=" options:NSCaseInsensitiveSearch];
        if (userRange.length == 0)
            // XXX maybe show an error message?
            return;
        NSUInteger authUserStartLocation = userRange.location + userRange.length;
        NSRange userEndRange = [query rangeOfString:@"&" options:NSCaseInsensitiveSearch 
                                              range:NSMakeRange(authUserStartLocation, [query length] - authUserStartLocation)];
        if (userEndRange.length) {
            authUser = [[query substringWithRange:NSMakeRange(authUserStartLocation, userEndRange.location - authUserStartLocation)]
                        stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        } else {
            authUser = [[query substringFromIndex:authUserStartLocation]
                        stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        }
        // token=
        NSString *authToken;
        NSRange tokenRange = [query rangeOfString:@"token=" options:NSCaseInsensitiveSearch];
        if (tokenRange.length == 0)
            // XXX maybe show an error message?
            return;
        NSUInteger authTokenStartLocation = tokenRange.location + tokenRange.length;
        NSRange tokenEndRange = [query rangeOfString:@"&" options:NSCaseInsensitiveSearch 
                                              range:NSMakeRange(authTokenStartLocation, [query length] - authTokenStartLocation)];
        if (tokenEndRange.length) {
            authToken = [[query substringWithRange:NSMakeRange(authTokenStartLocation, tokenEndRange.location - authTokenStartLocation)]
                         stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        } else {
            authToken = [[query substringFromIndex:authTokenStartLocation]
                         stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        }
        
        NSLog(@"query authUser: '%@', authToken: '%@'", authUser, authToken);
        if ([authUser length] && [authToken length]) {
            [[userDefaultsController values] setValue:authUser forKey:@"authUser"];
            [[userDefaultsController values] setValue:authToken forKey:@"authToken"];
            
            [self authenticateWithAuthUser:authUser authToken:authToken];
        }
        // XXX else maybe show an error message?
    }
    // XXX else maybe show an error message?
}

#pragma mark -
#pragma Actions

- (IBAction)showPithosBrowser:(id)sender {
    [pithosBrowserController showWindow:sender];
    [[pithosBrowserController window] makeKeyAndOrderFront:sender];
    [NSApp activateIgnoringOtherApps:YES];
}

- (IBAction)showPithosPreferences:(id)sender {
    [pithosPreferencesController showWindow:sender];
    [[pithosPreferencesController window] makeKeyAndOrderFront:sender];
    [NSApp activateIgnoringOtherApps:YES];
}

- (IBAction)aboutPithos:(id)sender {
    [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://pithos.dev.grnet.gr/docs"]];
}

#pragma mark -
#pragma Authentication

- (void)authenticateWithAuthUser:(NSString *)authUser authToken:(NSString *)authToken {
    NSLog(@"Authentication - storageURLPrefix:%@, authUser:%@, authToken:%@", storageURLPrefix, authUser, authToken);
    if ([authUser length] && [authToken length]) {
        [[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICacheForSessionDurationCacheStoragePolicy];
        [ASIPithosRequest setAuthURL:storageURLPrefix];
        [ASIPithosRequest setStorageURLPrefix:storageURLPrefix];
        [ASIPithosRequest setAuthUser:authUser];
        [ASIPithosRequest setAuthToken:authToken];
        [ASIPithosRequest setPublicURLPrefix:publicURLPrefix];
        
        [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAuthenticationCredentialsUpdated" object:self];
    }
}

@end
