/*
 *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
 *  Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */
#import <SystemConfiguration/SystemConfiguration.h>

#import "AppDelegate.h"

//lrc
#import <api/lrc.h>
#import <api/newaccountmodel.h>
#import <api/behaviorcontroller.h>
#import <api/conversation.h>
#import <api/newcallmodel.h>


#if ENABLE_SPARKLE
#import <Sparkle/Sparkle.h>
#endif

#import "Constants.h"
#import "RingWizardWC.h"
#import "DialpadWC.h"
#import "utils.h"

#if ENABLE_SPARKLE
@interface AppDelegate() <SUUpdaterDelegate>
#else
@interface AppDelegate()
#endif

@property RingWindowController* ringWindowController;
@property RingWizardWC* wizard;
@property DialpadWC* dialpad;
@property (nonatomic, strong) dispatch_queue_t scNetworkQueue;
@property (nonatomic, assign) SCNetworkReachabilityRef currentReachability;
@property (strong) id activity;

@end

NSString * const MESSAGE_NOTIFICATION = @"message_notification_type";
NSString * const CALL_NOTIFICATION = @"call_notification_type";
NSString * const CONTACT_REQUEST_NOTIFICATION = @"contact_request_notification_type";

NSString * const ACCOUNT_ID = @"account_id_notification_info";
NSString * const CALL_ID = @"call_id_notification_info";
NSString * const CONVERSATION_ID = @"conversation_id_notification_info";
NSString * const CONTACT_URI = @"contact_uri_notification_info";
NSString * const NOTIFICATION_TYPE = @"contact_type_notification_info";


@implementation AppDelegate {

std::unique_ptr<lrc::api::Lrc> lrc;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    // hide "Check for update" menu item when sparkle is disabled
    NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu];
    NSMenu *ringMenu = [[mainMenu itemAtIndex:0] submenu];
    NSMenuItem *updateItem = [ringMenu itemAtIndex:1];
#if ENABLE_SPARKLE
    updateItem.hidden = false;
#else
    updateItem.hidden = true;
#endif

#ifndef NDEBUG
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
#else
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
#endif

    [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];

    NSAppleEventManager* appleEventManager = [NSAppleEventManager sharedAppleEventManager];
    [appleEventManager setEventHandler:self andSelector:@selector(handleQuitEvent:withReplyEvent:) forEventClass:kCoreEventClass andEventID:kAEQuitApplication];

    dispatch_queue_t queue = NULL;
    queue = dispatch_queue_create("scNetworkReachability", DISPATCH_QUEUE_SERIAL);
    [self setScNetworkQueue:queue];
    [self beginObservingReachabilityStatus];
    NSActivityOptions options = NSActivitySuddenTerminationDisabled | NSActivityAutomaticTerminationDisabled | NSActivityBackground;
    self.activity = [[NSProcessInfo processInfo] beginActivityWithOptions:options reason:@"Receiving calls and messages"];
    lrc = std::make_unique<lrc::api::Lrc>();
    if([self checkForRingAccount]) {
        [self setRingtonePath];
        [self showMainWindow];
    } else {
        [self showWizard];
    }
    [self connect];
}

- (void) beginObservingReachabilityStatus
{
    SCNetworkReachabilityRef reachabilityRef = NULL;

    void (^callbackBlock)(SCNetworkReachabilityFlags) = ^(SCNetworkReachabilityFlags flags) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            lrc->connectivityChanged();
        });
    };

    SCNetworkReachabilityContext context = {
        .version = 0,
        .info = (void *)CFBridgingRetain(callbackBlock),
        .release = CFRelease
    };

    reachabilityRef = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, "test");
    if (SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context)){
        if (!SCNetworkReachabilitySetDispatchQueue(reachabilityRef, [self scNetworkQueue]) ){
            // Remove our callback if we can't use the queue
            SCNetworkReachabilitySetCallback(reachabilityRef, NULL, NULL);
        }
        [self setCurrentReachability:reachabilityRef];
    }
}

- (void) endObsvervingReachabilityStatusForHost:(NSString *)__unused host
{
    // Un-set the dispatch queue
    if (SCNetworkReachabilitySetDispatchQueue([self currentReachability], NULL) ){
        SCNetworkReachabilitySetCallback([self currentReachability], NULL, NULL);
    }
}

static void ReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkConnectionFlags flags, void* info)
{
    void (^callbackBlock)(SCNetworkReachabilityFlags) = (__bridge id)info;
    callbackBlock(flags);
}

- (void) connect
{
    QObject::connect(&lrc->getBehaviorController(),
                     &lrc::api::BehaviorController::newTrustRequest,
                     [self] (const QString& accountId, const QString& contactUri) {
        BOOL shouldNotify = [[NSUserDefaults standardUserDefaults] boolForKey:Preferences::ContactRequestNotifications];
        if(!shouldNotify) {
            return;
        }
        NSUserNotification* notification = [[NSUserNotification alloc] init];
        auto contactModel = lrc->getAccountModel()
        .getAccountInfo(accountId).contactModel.get();
        NSString* name = contactModel->getContact(contactUri)
        .registeredName.isEmpty() ?
        contactUri.toNSString():
        contactModel->getContact(contactUri).registeredName.toNSString();
        NSString* localizedMessage =
        NSLocalizedString(@"Send you a contact request",
                          @"Notification message");

        NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
        userInfo[ACCOUNT_ID] = accountId.toNSString();
        userInfo[CONTACT_URI] = contactUri.toNSString();
        userInfo[NOTIFICATION_TYPE] = CONTACT_REQUEST_NOTIFICATION;

        [notification setTitle: name];
        notification.informativeText = localizedMessage;
        [notification setSoundName:NSUserNotificationDefaultSoundName];
        [notification setUserInfo: userInfo];

        [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];

    });

    QObject::connect(&lrc->getBehaviorController(),
                     &lrc::api::BehaviorController::showIncomingCallView,
                     [self] (const QString& accountId, lrc::api::conversation::Info conversationInfo) {
        BOOL shouldNotify = [[NSUserDefaults standardUserDefaults] boolForKey:Preferences::CallNotifications];
        if(!shouldNotify) {
            return;
        }
        bool isIncoming = false;
        auto callModel = lrc->getAccountModel()
        .getAccountInfo(accountId).callModel.get();
        if(callModel->hasCall(conversationInfo.callId)) {
            isIncoming = !callModel->getCall(conversationInfo.callId).isOutgoing;
        }
        if(!isIncoming) {
            return;
        }
        NSString* name = bestIDForConversation(conversationInfo, *lrc->getAccountModel().getAccountInfo(accountId).conversationModel.get());
        NSUserNotification* notification = [[NSUserNotification alloc] init];

        NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
        userInfo[ACCOUNT_ID] = accountId.toNSString();
        userInfo[CALL_ID] = conversationInfo.callId.toNSString();
        userInfo[CONVERSATION_ID] = conversationInfo.uid.toNSString();
        userInfo[NOTIFICATION_TYPE] = CALL_NOTIFICATION;

        NSString* localizedTitle = [NSString stringWithFormat:
                                    NSLocalizedString(@"Incoming call from %@", @"Incoming call from {Name}"),
                                    name];
        // try to activate action button
        @try {
            [notification setValue:@YES forKey:@"_showsButtons"];
        }
        @catch (NSException *exception) {
            NSLog(@"Action button not activable on notification");
        }
        [notification setUserInfo: userInfo];
        [notification setOtherButtonTitle:NSLocalizedString(@"Refuse", @"Button Action")];
        [notification setActionButtonTitle:NSLocalizedString(@"Accept", @"Button Action")];
        [notification setTitle:localizedTitle];
        [notification setSoundName:NSUserNotificationDefaultSoundName];

        [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
    });

    QObject::connect(&lrc->getBehaviorController(),
                     &lrc::api::BehaviorController::newUnreadInteraction,
                     [self] (const QString& accountId, const QString& conversation,
                             uint64_t interactionId, const lrc::api::interaction::Info& interaction) {
        BOOL shouldNotify = [[NSUserDefaults standardUserDefaults] boolForKey:Preferences::MessagesNotifications];
        if(!shouldNotify) {
            return;
        }
        NSUserNotification* notification = [[NSUserNotification alloc] init];

        NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
        userInfo[ACCOUNT_ID] = accountId.toNSString();
        userInfo[CONVERSATION_ID] = conversation.toNSString();
        userInfo[NOTIFICATION_TYPE] = MESSAGE_NOTIFICATION;
        NSString* name = interaction.authorUri.toNSString();
        auto convIt = getConversationFromUid(conversation, *lrc->getAccountModel()
                                             .getAccountInfo(accountId)
                                             .conversationModel.get());
        auto convQueue = lrc->getAccountModel()
        .getAccountInfo(accountId)
        .conversationModel.get()->allFilteredConversations();
        if (convIt != convQueue.end()) {
            name = bestIDForConversation(*convIt, *lrc->getAccountModel().getAccountInfo(accountId).conversationModel.get());
        }
        NSString* localizedTitle = [NSString stringWithFormat:
                                    NSLocalizedString(@"Incoming message from %@",@"Incoming message from {Name}"),
                                    name];

        [notification setTitle:localizedTitle];
        [notification setSoundName:NSUserNotificationDefaultSoundName];
        [notification setSubtitle:interaction.body.toNSString()];
        [notification setUserInfo:userInfo];

        [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
    });
}

- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDismissAlert:(NSUserNotification *)alert {
    // check if user click refuse on incoming call notifications
    if(alert.activationType != NSUserNotificationActivationTypeNone) {
        return;
    }

    auto info = alert.userInfo;
    if(!info) {
        return;
    }
    NSString* identifier = info[NOTIFICATION_TYPE];
    NSString* callId = info[CALL_ID];
    NSString* accountId = info[ACCOUNT_ID];
    if(!identifier || !callId || !accountId) {
        return;
    }
    if([identifier isEqualToString: CALL_NOTIFICATION]) {
        auto accountInfo = &lrc->getAccountModel().getAccountInfo([accountId UTF8String]);
        if (accountInfo == nil)
            return;
        auto* callModel = accountInfo->callModel.get();
        callModel->hangUp([callId UTF8String]);
    }
}

- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
{
    auto info = notification.userInfo;
    if(!info) {
        return;
    }
    NSString* identifier = info[NOTIFICATION_TYPE];
    if([identifier isEqualToString: CALL_NOTIFICATION]) {
        if(notification.activationType == NSUserNotificationActivationTypeActionButtonClicked
           || notification.activationType == NSUserNotificationActivationTypeContentsClicked) {
            NSString* callId = info[CALL_ID];
            NSString* accountId = info[ACCOUNT_ID];
            NSString *conversationId = info[CONVERSATION_ID];
            auto accountInfo = &lrc->getAccountModel().getAccountInfo([accountId UTF8String]);
            if (accountInfo == nil)
                return;
            auto* callModel = accountInfo->callModel.get();
            callModel->accept([callId UTF8String]);
            [self.ringWindowController.window deminiaturize:self];
            [_ringWindowController showCall:callId forAccount:accountId forConversation:conversationId];
        }
    } else if(notification.activationType == NSUserNotificationActivationTypeContentsClicked) {
        [self.ringWindowController.window deminiaturize:self];
        if([identifier isEqualToString: MESSAGE_NOTIFICATION]) {
            NSString* accountId = info[ACCOUNT_ID];
            NSString *conversationId = info[CONVERSATION_ID];
            [_ringWindowController showConversation:conversationId forAccount:accountId];
        } else if([identifier isEqualToString: CONTACT_REQUEST_NOTIFICATION]) {
            NSString* accountId = info[ACCOUNT_ID];
            NSString *contactUri = info[CONTACT_URI];
            [_ringWindowController showContactRequestFor:accountId contactUri: contactUri];
        }
    }
    [[NSUserNotificationCenter defaultUserNotificationCenter] removeAllDeliveredNotifications];
}

- (void) showWizard
{
    if(self.wizard == nil) {
        self.wizard = [[RingWizardWC alloc] initWithNibName:@"RingWizard" bundle: nil accountmodel: &lrc->getAccountModel()];
    }
    [self.wizard.window makeKeyAndOrderFront:self];
}

- (void) showMainWindow
{
    if(self.ringWindowController == nil) {
        self.ringWindowController = [[RingWindowController alloc] initWithWindowNibName:@"RingWindow" bundle: nil accountModel:&lrc->getAccountModel() dataTransferModel:&lrc->getDataTransferModel() behaviourController:&lrc->getBehaviorController() avModel: &lrc->getAVModel()];
    }
    [[NSApplication sharedApplication] removeWindowsItem:self.wizard.window];
    self.wizard = nil;
    [self.ringWindowController.window makeKeyAndOrderFront:self];
}

- (void) showDialpad
{
    if (self.dialpad == nil) {
        self.dialpad = [[DialpadWC alloc] initWithWindowNibName:@"Dialpad"];
    }
    [self.dialpad.window makeKeyAndOrderFront:self];
}

-(QVector<QString>) getActiveCalls {
    return lrc->activeCalls();
}

-(QVector<QString>)getConferenceSubcalls:(QString)confId {
    return lrc->getConferenceSubcalls(confId);
}

-(void)setRingtonePath {
    QStringList accounts = lrc->getAccountModel().getAccountList();
    NSFileManager *fileManager = [NSFileManager defaultManager];
    for (auto account: accounts) {
        lrc::api::account::ConfProperties_t accountProperties = lrc->getAccountModel().getAccountConfig(account);
        NSString *ringtonePath = accountProperties.Ringtone.ringtonePath.toNSString();
        if (![fileManager fileExistsAtPath: ringtonePath]) {
            accountProperties.Ringtone.ringtonePath = [defaultRingtonePath() UTF8String];
            lrc->getAccountModel().setAccountConfig(account, accountProperties);
        }
    }
}

- (BOOL) checkForRingAccount
{
    return !lrc->getAccountModel().getAccountList().empty();
}

-(void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
    NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
    [appleEventManager setEventHandler:self
                           andSelector:@selector(handleGetURLEvent:withReplyEvent:)
                         forEventClass:kInternetEventClass andEventID:kAEGetURL];
}

- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
{
    if([self checkForRingAccount]) {
        [self showMainWindow];
    } else {
        [self showWizard];
    }
    return YES;
}

- (void)handleQuitEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{
    [[NSApplication sharedApplication] terminate:self];
}

-(void)applicationWillTerminate:(NSNotification *)notification
{
    [self cleanExit];
}

- (void) cleanExit
{
    if (self.activity != nil) {
        [[NSProcessInfo processInfo] endActivity:self.activity];
        self.activity = nil;
    }
    [self.wizard close];
    [self.ringWindowController close];
    lrc.reset();
}

#if ENABLE_SPARKLE

#pragma mark - Sparkle delegate

- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update
{
    [NSApp activateIgnoringOtherApps:YES];
}

- (BOOL)updaterMayCheckForUpdates:(SUUpdater *)bundle
{
    return YES;
}

- (BOOL)updaterShouldRelaunchApplication:(SUUpdater *)updater
{
    return YES;
}

- (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error
{
    NSLog(@"Error:%@", error.localizedDescription);
}

#endif
@end
