/*
 *  Copyright (C) 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 "RegisterNameWC.h"


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

//LRC
#import <accountmodel.h>
#import <QItemSelectionModel>
#import <account.h>

#import "AppDelegate.h"

@interface RegisterNameWC ()
@end

@implementation RegisterNameWC
{
    __unsafe_unretained IBOutlet NSTextField* registeredNameField;
    __unsafe_unretained IBOutlet NSSecureTextField* passwordField;
    __unsafe_unretained IBOutlet NSImageView* ivLookupResult;
    __unsafe_unretained IBOutlet NSProgressIndicator* indicatorLookupResult;

    __unsafe_unretained IBOutlet NSProgressIndicator *registrationProgress;

    QMetaObject::Connection registrationEnded;
    QMetaObject::Connection registeredNameFound;

    BOOL lookupQueued;
    NSString* usernameWaitingForLookupResult;
}

NSInteger const BLOCKCHAIN_NAME_TAG             = 2;

- (id)initWithDelegate:(id <LoadingWCDelegate>) del
{
    return [self initWithDelegate:del actionCode:0];
}

- (id)initWithDelegate:(id <RegisterNameDelegate>) del actionCode:(NSInteger) code
{
    return [super initWithWindowNibName:@"RegisterNameWindow" delegate:del actionCode:code];
}

- (void)windowDidLoad
{
    [super windowDidLoad];
    [registeredNameField setTag:BLOCKCHAIN_NAME_TAG];
    self.registeredName = @"";
    [ivLookupResult setHidden:YES];
    [indicatorLookupResult setHidden:YES];
}

#pragma mark - Input validation

- (BOOL)isPasswordValid
{
    return self.password.length >= 6;
}

#pragma mark - Username validation delegate methods

- (BOOL)userNameAvailable
{
    return (self.registeredName.length > 0 && self.isUserNameAvailable);
}

- (void)showLookUpAvailable:(BOOL)available andText:(NSString *)message
{
    [ivLookupResult setImage:[NSImage imageNamed:(available?@"ic_action_accept":@"ic_action_cancel")]] ;
    [ivLookupResult setHidden:NO];
    [ivLookupResult setToolTip:message];
}

- (void)onUsernameAvailabilityChangedWithNewAvailability:(BOOL)newAvailability
{
    self.isUserNameAvailable = newAvailability;
}

- (void)hideLookupSpinner
{
    [indicatorLookupResult setHidden:YES];
}

- (void)showLookupSpinner
{
    [ivLookupResult setHidden:YES];
    [indicatorLookupResult setHidden:NO];
    [indicatorLookupResult startAnimation:nil];
}

- (BOOL)lookupUserName
{
    [self showLookupSpinner];
    QObject::disconnect(registeredNameFound);
    registeredNameFound = QObject::connect(
                                           &NameDirectory::instance(),
                                           &NameDirectory::registeredNameFound,
                                           [=] ( const Account* account, NameDirectory::LookupStatus status,  const QString& address, const QString& name) {
                                               NSLog(@"Name lookup ended");
                                               lookupQueued = NO;
                                               //If this is the username we are waiting for, we can disconnect.
                                               if (name.compare(QString::fromNSString(usernameWaitingForLookupResult)) == 0) {
                                                   QObject::disconnect(registeredNameFound);
                                               } else {
                                                   //Keep waiting...
                                                   return;
                                               }

                                               //We may now stop the spinner
                                               [self hideLookupSpinner];

                                               BOOL isAvailable = NO;
                                               NSString* message;
                                               switch(status)
                                               {
                                                   case NameDirectory::LookupStatus::SUCCESS:
                                                   {
                                                       message = NSLocalizedString(@"The entered username is not available",
                                                                                   @"Text shown to user when his username is already registered");
                                                       isAvailable = NO;
                                                       break;
                                                   }
                                                   case NameDirectory::LookupStatus::NOT_FOUND:
                                                   {
                                                       message = NSLocalizedString(@"The entered username is available",
                                                                                   @"Text shown to user when his username is available to be registered");
                                                       isAvailable = YES;
                                                       break;
                                                   }
                                                   case NameDirectory::LookupStatus::INVALID_NAME:
                                                   {
                                                       message = NSLocalizedString(@"The entered username is invalid. It must have at least 3 characters and contain only lowercase alphanumeric characters.",
                                                                                   @"Text shown to user when his username is invalid to be registered");
                                                       isAvailable = NO;
                                                       break;
                                                   }
                                                   case NameDirectory::LookupStatus::ERROR:
                                                   default:
                                                   {
                                                       message = NSLocalizedString(@"Failed to perform lookup",
                                                                                   @"Text shown to user when an error occur at registration");
                                                       isAvailable = NO;
                                                       break;
                                                   }
                                               }
                                               [self showLookUpAvailable:isAvailable andText: message];
                                               [self onUsernameAvailabilityChangedWithNewAvailability:isAvailable];

                                           }
                                           );

    //Start the lookup in a second so that the UI dosen't seem to freeze
    BOOL result = NameDirectory::instance().lookupName(nullptr, QString(), QString::fromNSString(usernameWaitingForLookupResult));

}

- (void)controlTextDidChange:(NSNotification *)notif
{
    NSTextField* textField = [notif object];
    if (textField.tag != BLOCKCHAIN_NAME_TAG) {
        return;
    }
    NSString* alias = textField.stringValue;

    [self showLookupSpinner];
    [self onUsernameAvailabilityChangedWithNewAvailability:NO];
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [self performSelector:@selector(lookUp:) withObject:alias afterDelay:0.5];
}

- (void) lookUp:(NSString*) name
{
    if (!lookupQueued) {
        usernameWaitingForLookupResult = name;
        lookupQueued = YES;
        [self lookupUserName];
    }
}

#pragma mark - Registration process

- (IBAction)registerUsername:(id)sender
{
    [registrationProgress startAnimation:nil];
    [self showLoading];
    [self setCallback];

    self.isUserNameAvailable = AccountModel::instance().selectedAccount()->registerName(QString::fromNSString(self.password),
                                                                                        QString::fromNSString(self.registeredName));
    if (!self.isUserNameAvailable) {
        NSLog(@"Could not initialize registerName operation");
        QObject::disconnect(registrationEnded);
    }
}

- (void)setCallback
{
    QObject::disconnect(registrationEnded);
    registrationEnded = QObject::connect(AccountModel::instance().selectedAccount(),
                                         &Account::nameRegistrationEnded,
                                         [=] (NameDirectory::RegisterNameStatus status,  const QString& name)
                                         {
                                             QObject::disconnect(registrationEnded);
                                             switch(status) {
                                                 case NameDirectory::RegisterNameStatus::WRONG_PASSWORD:
                                                 case NameDirectory::RegisterNameStatus::ALREADY_TAKEN:
                                                 case NameDirectory::RegisterNameStatus::NETWORK_ERROR:
                                                     [self showError];
                                                     break;
                                                 case NameDirectory::RegisterNameStatus::SUCCESS:
                                                     [self.delegate didRegisterNameWithSuccess];
                                                     // Artificial refresh of the model to update the welcome view
                                                     Q_EMIT AccountModel::instance().dataChanged(QModelIndex(), QModelIndex());
                                                     break;
                                             }
                                         });
}


+ (NSSet *)keyPathsForValuesAffectingUserNameAvailableORNotBlockchain
{
    return [NSSet setWithObjects: NSStringFromSelector(@selector(isUserNameAvailable)), nil];
}

+ (NSSet *)keyPathsForValuesAffectingIsPasswordValid
{
    return [NSSet setWithObjects:@"password", nil];
}

@end
