//
//  MPRegistrationUtils.h
//  Memphis
//
//  Created by Dmitry Gaponenko on 9/24/13.
//  Copyright (c) 2013 MacPhun LLC. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "MPServiceUtils.h"

#define kMPGroupContainerIdentifier [[NSString stringWithFormat:@"%@.%@", [MPServiceUtils containerIdentifier], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]] stringByReplacingOccurrencesOfString:@".photoextension" withString:@""]

@class MPServiceUtils;

extern NSString *const MPShowActivationControllerNotification;
extern NSString *const MPActivationSuccessNotification;

typedef enum _MPSerialValidationResult
{
    MPResultUndefined = -1,
    MPSuccessfullyValidated,
    MPInvalidSerialNumberError,
    MPInvalidUserNameError,
    MPMacAddressesLimitOverflowError,
    MPNoSuchMacAddressInDBError,
    MPInvalidEmailAddressInDBError,
    MPConnectionToDBFailed,
    MPStoredFunctionCallFailed,
    MPSerialOnlyForDiscount
} MPSerialValidationResult;

typedef void(^MPRegistrationUtilsCallbackBlock)(MPSerialValidationResult validationResult);
typedef void(^MPRegistrationUtilsCheckTrialCallbackBlock)(MPSerialValidationResult validationResult, NSUInteger validatedDays);
typedef void(^MPRegistrationUtilsCallbackGetServiceNameBlock)(NSString* serviceName);

typedef void(^MPRegistrationUtilsTrialCallbackBlock)(MPSerialValidationResult validationResult, NSDate *expirationDate);


NS_INLINE BOOL allowRunVersion();

@interface MPRegistrationUtils : NSObject

+ (BOOL)allowRunVersion;
+ (NSUInteger)cachedTrialDaysLeft;
+ (void)validateSerial:(NSString*)serial forUserName:(NSString*)userName andEmail:(NSString*)email macAddress:(NSString*)address atTheFirstLaunch:(BOOL)firstLaunch completionHandler:(MPRegistrationUtilsCallbackBlock)completionHandler;
+ (MPSerialValidationResult)validateSerial:(NSString*)serial forUserName:(NSString*)userName andEmail:(NSString*)email macAddress:(NSString*)address atTheFirstLaunch:(BOOL)firstLaunch;
+ (void)validateTrialForUserName:(NSString*)userName andEmail:(NSString*)email macAddress:(NSString*)address completionHandler:(MPRegistrationUtilsCheckTrialCallbackBlock)completionHandler;
+ (MPSerialValidationResult)validateTrialForUserName:(NSString*)userName andEmail:(NSString*)email macAddress:(NSString*)address validatedDays:(NSInteger*)days;
+ (MPSerialValidationResult)validateTrialForUserName:(NSString*)userName andEmail:(NSString*)email macAddress:(NSString*)address validatedDays:(NSInteger*)days applicationName:(NSString*)appName;

+ (BOOL)saveEmailToRemoteDatabase:(NSString*)email;
+ (void)showErrorMaxCountOfUsers;
+ (void)addNewMacAddressIfCan;
+ (void)checkActivationKey;
+ (BOOL)isActivated;
+ (void)setNeedsShowActivationCotroller;

+ (void)setRegistrationUtilsActivationKey:(NSString *)key;
+ (NSString *)registrationUtilsActivationKey;

+ (void)setRegistrationUtilsIndexKey:(NSString *)key;
+ (NSString *)registrationUtilsIndexKey;

+ (void)setRegistrationUtilsEmailKey:(NSString *)key;
+ (NSString *)registrationUtilsEmailKey;

+ (void)setRegistrationUtilsUserNameKey:(NSString *)key;
+ (NSString *)registrationUtilsUserNameKey;

+ (void)setRegistrationUtilsTrialVersionKey:(NSString *)key;
+ (NSString *)registrationUtilsTrialVersionKey;

+ (void)successfullyValidatedForKey:(NSString*)activationKey email:(NSString*)email;

+ (void)copyActivationToSharedPlist;

#ifdef DEBUG
+ (void)testForDebugActivationWithTime:(int)randomtime;
#endif

+ (void)serviceNameForSerial:(NSString*)serial completionHandler:(MPRegistrationUtilsCallbackGetServiceNameBlock)completionHandler;
+ (NSString*)serviceNameForSerial:(NSString*)serial;
+ (NSInteger)allowedCountOfDevicesForSerial:(NSString *)serial;

+ (void)clearActivationInfo;

@end

#if (NA_VERSION && !PHOTO_EXT)
#define MP_DEFINE_CHECK(RANDOMTIME)\
u_int32_t r = arc4random_uniform(RANDOMTIME);\
BOOL isTrial = NO;\
isTrial = [[NSUserDefaults standardUserDefaults] boolForKey:[MPRegistrationUtils registrationUtilsTrialVersionKey]];\
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(r * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{\
NSString* activationKey = nil;\
if ([[NSUserDefaults standardUserDefaults] objectForKey:[MPRegistrationUtils registrationUtilsActivationKey]])\
activationKey = [[NSUserDefaults standardUserDefaults] stringForKey:[MPRegistrationUtils registrationUtilsActivationKey]];\
NSString* userName = [[NSUserDefaults standardUserDefaults] stringForKey:[MPRegistrationUtils registrationUtilsUserNameKey]];\
NSString* email = [[NSUserDefaults standardUserDefaults] stringForKey:[MPRegistrationUtils registrationUtilsEmailKey]];\
NSString* hash = nil;\
if ([[NSUserDefaults standardUserDefaults] objectForKey:[MPRegistrationUtils registrationUtilsIndexKey]])\
hash = [[NSUserDefaults standardUserDefaults] stringForKey:[MPRegistrationUtils registrationUtilsIndexKey]];\
\
NSURL *url = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kMPGroupContainerIdentifier];\
NSString *activationPlistPath = [[url path] stringByAppendingPathComponent:@"license.plist"];\
NSDictionary *activationDict = [NSDictionary dictionaryWithContentsOfFile:activationPlistPath];\
\
if (activationKey == nil && [activationDict.allKeys containsObject:[MPRegistrationUtils registrationUtilsActivationKey]]) {\
activationKey = [activationDict objectForKey:[MPRegistrationUtils registrationUtilsActivationKey]];\
hash = nil;\
}\
\
if (hash == nil && [activationDict.allKeys containsObject:[MPRegistrationUtils registrationUtilsIndexKey]]) {\
hash = [activationDict objectForKey:[MPRegistrationUtils registrationUtilsIndexKey]];\
}\
if (email == nil && [activationDict.allKeys containsObject:[MPRegistrationUtils registrationUtilsEmailKey]]) {\
email = [activationDict objectForKey:[MPRegistrationUtils registrationUtilsEmailKey]];\
}\
\
if (activationKey && [activationKey length] == 24 && hash)\
{\
NSString* hashCurrent = [MPServiceUtils hashStringFromString:[activationKey stringByAppendingString:[MPServiceUtils hardwareUUID]]];\
if (![hashCurrent isEqualToString:hash])\
{\
[MPRegistrationUtils clearActivationInfo];\
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{\
exit(132);\
});\
}\
}\
else if (hash && userName && email && isTrial && [[MPServiceUtils hashStringFromString:[[MPRegistrationUtils registrationUtilsTrialVersionKey] stringByAppendingString:[MPServiceUtils hardwareUUID]]] isEqualToString:hash])\
{}\
else\
{\
[MPRegistrationUtils clearActivationInfo];\
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{\
exit(133);\
});\
}\
});
#else
#define MP_DEFINE_CHECK(RANDOMTIME)
#endif
