/**
 * NPCI
 * Copyright (C) 2022 NPCI
 *
 * This program is developed for usage by NPCI only.
 * Any distribution of this code
 * in any format is strictly prohibited without the express
 * permission of NPCI.
 *
 */

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#define ERRORDOMAIN @"CommonLibrary"

FOUNDATION_EXPORT NSString *const CL_VERSION;
FOUNDATION_EXPORT NSString *const LITE_CL_VERSION;
FOUNDATION_EXPORT NSString *const CL_SUB_VERSION;
FOUNDATION_EXPORT NSString *const LITE_CL_SUB_VERSION;

typedef void (^ResponseBlock)(NSDictionary *response);

@interface CLServices : NSObject <NSXMLParserDelegate>


/** Returns true if challenge is a valid string.
 @brief Get the challenge (string pointer) with deviceId, appId, type - type may be "Initial" or "Rotate"
 @author NPCI
 @copyright NPCI
 @note getChallengeForDeviceId is called in two modes "Initial" or "Rotate"
 @since library version 1.0
 @todo Initially when the app is launched then the function is called in "Initial" mode then challenge is found that is valid for 30days, after 30 days it is called in "Rotate" mode
 @version 1.5
 @result pointer to string - challenge
 @return BOOL
 @code BOOL success = [CLServices getChallengeForDeviceId:device_id appID: App_id type:@"Initial" challenge:&challenge error:&error]; ////initial
 NSTimeInterval interval = [previous_date timeIntervalSinceNow];
 if (interval>2592000) ///interval for 30 days
 {
 BOOL success = [CLServices getChallengeForDeviceId: device_id appID: App_id type:@"Rotate" challenge:&challenge error:&error];
 }
 @params deviceId, appId, type
 */

+(BOOL)getChallengeForDeviceId :(NSString*)device_id appId:(NSString*)app_id type: (NSString*)type challenge:(NSString**)challenge error:(NSError**)error;
/** Returns true if hmac is valid with respect of appid, mobile, deviceID.
 @brief validation of hmac (generated with appId, mobile number, deviceID hash) with the actual parameters
 @author NPCI
 @copyright NPCI
 @note registerAppWithHmac is called with hmac generated by app with deviceId, appId and mobile number
 @since library version 1.0
 @version 1.5
 @result BOOL - hmac is valid against provided appid, mobile, deviceId.
 @return BOOL
 @code BOOL success_register= [CLServices registerAppWithHmac:hmac appID: App_id mobile:mobile_number deviceID: device_id error:&register_error];
 @params hmac, appId, mobile, deviceId
 */

+(BOOL)registerAppWithHmac : (NSString*)hmac appID: (NSString*)app_id mobile: (NSString*)mobile deviceID: (NSString*)device_id error:(NSError**)error random:(NSString*)randomStr;

/** getCredentialsPresentedFrom is called during transaction
 @brief this function is used to create common library input fields for many consequences such as or balance enquiry, for normal pay transaction, for setting new Mpin or mobile number verification
 @author NPCI
 @copyright NPCI
 @since library version 1.0
 @todo the function is called during any type of 3rd party transaction
 @version 1.5
 @result if successful then credentials are returned as a dictionary
 
 @code [CLServices getCredentialsPresentedFrom:self
             controls:controls
             keyCode:keyCode
             keyXMLPayload:xml
             configuration:configuration
             salt:salt
             trust:trust
             payInfo:payInfoArray
             language:langPref
             completionHandler:^(int code, NSError *error, NSDictionary *data, ResponseBlock clCallback)
     {
         if (code==1 && data) {
             //Credblocks received
         } else if (code == 2 && clCallback) {
             //Trigger OTP
             //After OTP is received notify CL. 0 for success, -1 for failure.
             clCallback(@{@"status":@"0"});
         } else if(code==3) {
             //Trigger forgot MPIN flow
         } else {
             //Error has occurred check error object for details.
             NSLog (@"Error-%@", error);
         }
     }
 ];
 @params
 1. viewController object on which common library is presented
 2. controls dictionary
 3. KeyCode
 4. xml string
 5. configuration
 6. salt
 7. trust
 8. payInfo
 9. language
 */

+(void)getCredentialsPresentedFrom:(UIViewController*)viewController controls:(NSDictionary*)controls keyCode:(NSString*)keyCode keyXMLPayload:(NSString*)keyXMLPayload configuration:(NSDictionary*)configuration salt:(NSDictionary*)salt trust:(NSString*)trust payInfo:(NSArray*)payInfo language:(NSString*)language completionHandler:(void(^)(int ,NSError *,NSDictionary*,ResponseBlock clCallback))completionHandler;

/** Returns true if challenge is a valid string.

 @brief Get the challenge (string pointer) with deviceId, appId, type - type may be "Initial" or "Rotate"
 @author NPCI
 @copyright NPCI
 @note getChallengeForDeviceId is called in two modes "Initial" or "Rotate"
 @remarks getChallengeForDeviceId is a class function calling function as:        BOOL success = [CLServices getChallengeForDeviceId: device_id appID: App_id type:@"Initial" challenge:&challenge error:&error];
 @since library version 1.6
 @todo Initially when the app is launched then the function is called in "Initial" mode then challenge is found that is valid for 30days, after 30 days it is called in "Rotate" mode
 @version 1.6
 @result pointer to string - challenge
 @return BOOL
 @code BOOL success = [CLServices getChallengeForDeviceId: device_id appID: App_id type:@"Initial" challenge:&challenge error:&error]; ////initial
 NSTimeInterval interval = [previous_date timeIntervalSinceNow];
 if (interval>2592000) ///interval for 30 days
 {
     BOOL success = [CLServices getChallengeForDeviceId: device_id appID: App_id type: @"Rotate" challenge: &challenge error: &error];
 }
 
 @params deviceId, appId, type, appGroup
 */

+(BOOL)getChallengeForDeviceId :(NSString*)device_id appId:(NSString*)app_id type: (NSString*)type challenge:(NSString**)challenge appGroup:(NSString*)appGroup error:(NSError**)error;

/** Returns true if hmac is valid with respect of appid, mobile, deviceID.
 @brief validation of hmac (generated with appId, mobile number, deviceID hash) with the actual parameters
 @author NPCI
 @copyright NPCI
 @note registerAppWithHmac is called with hmac generated by app with deviceId, appId and mobile number
 @since library version 1.6
 @version 1.6
 @result BOOL - hmac is valid against provided appid, mobile, deviceId.
 @return BOOL
 @code BOOL success_register= [CLServices registerAppWithHmac: hmac appID: App_id mobile:@"919002050725" deviceID: device_id random:@"l2nd5pSeC7L1deQ=" error:&register_error];
 @params hmac, appId, mobile, deviceId, appGroup, random
 */

+(BOOL)registerAppWithHmac: (NSString*)hmac appID: (NSString*)app_id mobile: (NSString*)mobile deviceID: (NSString*)device_id appGroup:(NSString*)appGroup error:(NSError**)error random:(NSString*)randomStr;

/** getCredentialsPresentedFrom is called during transaction
 @brief this function is used to create common library input fields for many consequences such as or balance enquiry, for normal pay transaction, for setting new Mpin or mobile number verification
 
 @author NPCI
 @copyright NPCI
 @since library version 1.6
 @todo the function is called during any type of 3rd party transaction
 @version 1.0
 @result if successful then credentials are returned as a dictionary
 
 @code [CLServices getCredentialsPresentedFrom:self
             controls:controls
             keyCode:keyCode
             keyXMLPayload:xml
             configuration:configuration
             salt:salt
             trust:trust
             payInfo:payInfoArray
             language:langPref
             appGroup:appGroup
             completionHandler:^(int code, NSError *error, NSDictionary *data, ResponseBlock clCallback)
     {
         if (code==1 && data) {
             //Credblocks received
         } else if (code == 2 && clCallback) {
             //Trigger OTP
             //After OTP is received notify CL. 0 for success, -1 for failure.
             clCallback(@{@"status": @"0"});
         } else if(code==3) {
             //Trigger forgot MPIN flow
         } else {
             //Error has occurred check error object for details.
             NSLog (@"Error-%@”, error);
         }
     }
 ];
 
 @params
 1. view controller object on which common library is presented
 2. controls dictionary
 3. KeyCode
 4. xml string
 5. configuration
 6. salt
 7. trust
 8. payInfo
 9. language
 10. appGroup
 */

+(void)getCredentialsPresentedFrom:(UIViewController*)viewController controls:(NSDictionary*)controls keyCode:(NSString*)keyCode keyXMLPayload:(NSString*)keyXMLPayload configuration:(NSDictionary*)configuration salt:(NSDictionary*)salt trust:(NSString*)trust payInfo:(NSArray*)payInfo language:(NSString*)language appGroup:(NSString*)appGroup completionHandler:(void(^)(int ,NSError *,NSDictionary*,ResponseBlock clCallback))completionHandler;


/** Returns true if UPI lite is supported
 @brief this function is used to check UPI lite feasibility for a device/OS version
 
 @author NPCI
 @copyright NPCI
 @since library version 1.8
 @version 1.8
 @return BOOL
 */

+ (BOOL)isUpiLiteSupported;


/** Returns true if UPI lite is already bound
 @brief this function is used to check if UPI lite is already bound for an account in the device
 
 @author NPCI
 @copyright NPCI
 @since library version 1.8
 @version 1.8
 @return NSString - JSON String with key status and syncRequired(only if status is "BOUND")
 @code NSString *response = [CLServices isUpiLiteBoundForMobileNumber:mobileNumber deviceId:deviceId accountRef:accountRef];
        // response - '{"status":"NO_BIND"/"BOUND","syncRequired":"true"/"false"}'
 @params
 1. mobileNumber
 2. deviceId
 3. accountRef
 */

+ (NSString *)isUpiLiteBoundForMobileNumber:(NSString *)mobile deviceId:(NSString *)deviceId accountRef:(NSString *)accountRef;


/** Returns true if UPI lite unbinding is successful
 @brief this function is used to delete the lite related data from customer’s device
 
 @author NPCI
 @copyright NPCI
 @since library version 1.8
 @version 1.8
 @return BOOL
 @code BOOL status = [CLServices unBindDeviceForMobileNumber:mobileNumber deviceId:deviceId accountRef:accountRef];
 @params
 1. mobileNumber
 2. deviceId
 3. accountRef
 */

+ (BOOL)unBindDeviceForMobileNumber:(NSString *)mobile deviceId:(NSString *)deviceId accountRef:(NSString *)accountRef;


/** Gives status true if UPI lite onboarding is successfully registered in the device.
 @brief this function is used to store device certificate and account state from the XML that was received from server in the response of UPI lite onboarding.
 
 @author NPCI
 @copyright NPCI
 @since library version 1.8
 @version 1.8
 @result BOOL - XML payload is valid and device certificate & account state are succesfully stored in the device.
 @code [CLServices registerUPILiteOnboardingForMobileNumber:mobileNumber deviceId:deviceId accountRef:accountRef xmlPayload:xmlPayload completionHandler:^(BOOL status) {
     if (status) {
        // Trigger load money flow if it's not lite keys rotation flow
     } else {
            
     }
 }];
 @params
 1. mobileNumber
 2. deviceId
 3. accountRef
 4. xmlPayload
 */

+ (void)registerUPILiteOnboardingForMobileNumber:(NSString *)mobile deviceId:(NSString *)deviceId accountRef:(NSString *)accountRef xmlPayload:(NSString *)xmlPayload completionHandler:(void(^)(BOOL status))completionHandler;


/** Returns true if riskParams are successfully updated in the device.
 @brief this function is used to store an String (riskParams) which was generated by NPCI in response to the Load Money/TopUP.
 @author NPCI
 @copyright NPCI
 @since library version 1.8
 @todo Psp app should fetch the latest state of lite account from NPCI and update it using registerUPILiteState.
 @version 1.8
 @result BOOL - XML payload is valid and device certificate & account state are succesfully stored in the device.
 @code BOOL status = [CLServices registerUPILiteStateForMobileNumber:mobileNumber deviceId:deviceId accountRef:accountRef riskParams:riskParams];
 @params
 1. mobileNumber
 2. deviceId
 3. accountRef
 4. riskParams
 */

+ (BOOL)registerUPILiteStateForMobileNumber:(NSString *)mobile deviceId:(NSString *)deviceId accountRef:(NSString *)accountRef riskParams:(NSString *)riskParams;


/** Returns UPI lite balance for the account.
 @brief this function is used to get the lite account balance
 @author NPCI
 @copyright NPCI
 @since library version 1.8
 @version 1.8
 @result NSString - UPI lite balance of the account.
 @code NSString *balance = [CLServices getUPILiteBalanceForMobileNumber:mobileNumber deviceId:deviceId accountRef:accountRef];
 @params
 1. mobileNumber
 2. deviceId
 3. accountRef
 */

+ (NSString *)getUPILiteBalanceForMobileNumber:(NSString *)mobile deviceId:(NSString *)deviceId accountRef:(NSString *)accountRef;

@end

