//  RCTMPosControllerConfigProxy.m
//  RNBixolonBgateLibs
//  Created by JCLEE on 2021/09/15.

#import <React/RCTLog.h>
#import "RCTMPosControllerConfigProxy.h"
@import frameworkMPosSDK;

@interface RCTMPosControllerConfigProxy()
@property MPosControllerConfig* config;
@end

@implementation RCTMPosControllerConfigProxy

+ (BOOL)requiresMainQueueSetup {
    return NO;
}

- (id)init{
    if((self=[super init])){
#ifdef DEBUG
        [MPosControllerConfig setEnableLog:YES saveFile:NO saveToHex:NO];
#endif
        _config = [MPosControllerConfig new];
    }
    return self;
}

RCT_EXPORT_METHOD(selectInterface:(NSInteger)interfaceType
                  address:(NSString*)address
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    MPOS_RESULT result = [_config selectInterface:interfaceType address:address];
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}


RCT_EXPORT_METHOD(selectCommandMode:(NSInteger)commandMode
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    MPOS_RESULT result = [_config selectCommandMode:commandMode];
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}

RCT_EXPORT_METHOD(openService:(NSInteger)deviceID
                  timeout:(NSInteger)timeout
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    [_config setTimeout: timeout];
    MPOS_RESULT result = [_config openService:deviceID];
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}

RCT_EXPORT_METHOD(closeService:(NSInteger)timeout
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    MPOS_RESULT result = [_config closeService:timeout];
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}

RCT_EXPORT_METHOD(setTransaction:(NSInteger)mode
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    MPOS_RESULT result = [_config setTransaction:mode];
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}

RCT_EXPORT_METHOD(setReadMode:(NSInteger)mode
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    MPOS_RESULT result = [_config setReadMode:mode];
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}

RCT_EXPORT_METHOD(setKeepNetworkConnection:(NSInteger)enable
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    [_config setKeepNetworkConnection:enable];
    resolve([NSNumber numberWithInteger:0]);
}

RCT_EXPORT_METHOD(getDeviceId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    NSInteger deviceId = [_config getDeviceId];
    if(deviceId < 0){
        reject(@"FAIL", [NSString stringWithFormat:@"DEVICE_ID: %ld",(long)deviceId], nil);
        return;
    }
    resolve([NSNumber numberWithInteger:deviceId]);
}

RCT_EXPORT_METHOD(isOpen:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    NSInteger isOpen = [_config isOpen];
    resolve([NSNumber numberWithInteger:isOpen]);
}

RCT_EXPORT_METHOD(getSDKVersion:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    resolve([_config getSDKVersion]);
}

RCT_EXPORT_METHOD(directIO:(NSArray<NSNumber*>*)data
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    NSMutableData* dataToSend = [NSMutableData data];
    for(NSNumber* number in data){
        char byte = [number charValue];
        [dataToSend appendBytes: &byte length:1];
    }
    MPOS_RESULT result = [_config directIO:dataToSend];
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}

RCT_EXPORT_METHOD(searchDevices:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    NSArray<NSNumber*>* list = [_config searchDevices];
    if(![list count]){
        reject(@"FAIL", @"NO_DEVICE_ID", nil);
        return;
    }else{
        resolve(list);
    }
}

RCT_EXPORT_METHOD(getBgateSerialNumber:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    resolve([_config getBgateSerialNumber]);
}

RCT_EXPORT_METHOD(getUSBDevice:(NSInteger)deviceId resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    resolve([_config getUSBDevice:deviceId]);
}

RCT_EXPORT_METHOD(getCustomDevices:(NSInteger)deviceType resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    resolve([_config getCustomDevices:deviceType]);
}

RCT_EXPORT_METHOD(getSerialConfig:(NSInteger)deviceId resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    resolve([_config getSerialConfig:deviceId]);
}

RCT_EXPORT_METHOD(getSerialConfiguration:(NSInteger)deviceId resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    resolve([_config getSerialConfiguration:deviceId]);
}

RCT_EXPORT_METHOD(setSerialConfig:(NSInteger)deviceId
                  baudRate:(NSInteger)baudRate
                  dataBit:(NSInteger)dataBit
                  stopBit:(NSInteger)stopBit
                  parityBit:(NSInteger)parityBit
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    MPOS_RESULT result = [_config setSerialConfig:deviceId
                                         baudRate:baudRate
                                          dataBit:dataBit
                                          stopBit:stopBit
                                        parityBit:parityBit];
    
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}

RCT_EXPORT_METHOD(setSerialConfiguration:(NSInteger)deviceId
                  baudRate:(NSInteger)baudRate
                  dataBit:(NSInteger)dataBit
                  stopBit:(NSInteger)stopBit
                  parityBit:(NSInteger)parityBit
                  flowControl:(NSInteger)flowControl
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    MPOS_RESULT result = [_config setSerialConfiguration:deviceId
                                                baudRate:baudRate
                                                 dataBit:dataBit
                                                 stopBit:stopBit
                                               parityBit:parityBit
                                             flowControl:flowControl];
    
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}

RCT_EXPORT_METHOD(addCustomDevice:(NSInteger)deviceType
                  vid:(NSString*)vid
                  pid:(NSString*)pid
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    MPOS_RESULT result = [_config addCustomDevice:deviceType vid:vid pid:pid];
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}

RCT_EXPORT_METHOD(deleteCustomDevice:(NSInteger)deviceType
                  vid:(NSString*)vid
                  pid:(NSString*)pid
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    MPOS_RESULT result = [_config deleteCustomDevice:deviceType vid:vid pid:pid];
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}

RCT_EXPORT_METHOD(reInitCustomDeviceType:(NSInteger)deviceType
                  resolve:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    MPOS_RESULT result = [_config reInitCustomDeviceType:deviceType];
    NSString* resultMsg = [NSString stringWithFormat:@"RESULT_CODE: %ld",(long)result];
    if(result != MPOS_SUCCESS){
        reject(@"FAIL", resultMsg, nil);
        return;
    }
    resolve([NSNumber numberWithInteger:result]);
}


RCT_EXPORT_MODULE();

@end


