#ifndef BarcodeMapping_h
#define BarcodeMapping_h
#import "InternalScanbotStorageUtils.h"

static inline SBSDKBarcodeType* barcodeTypeFromString(NSString* string) {
    if ([string isEqualToString:@"AZTEC"]) return SBSDKBarcodeTypeAztec;
    if ([string isEqualToString:@"CODABAR"]) return SBSDKBarcodeTypeCodaBar;
    if ([string isEqualToString:@"CODE_128"]) return SBSDKBarcodeTypeCode128;
    if ([string isEqualToString:@"CODE_39"]) return SBSDKBarcodeTypeCode39;
    if ([string isEqualToString:@"CODE_93"]) return SBSDKBarcodeTypeCode93;
    if ([string isEqualToString:@"DATA_MATRIX"]) return SBSDKBarcodeTypeDataMatrix;
    if ([string isEqualToString:@"EAN_13"]) return SBSDKBarcodeTypeEAN13;
    if ([string isEqualToString:@"EAN_8"]) return SBSDKBarcodeTypeEAN8;
    if ([string isEqualToString:@"ITF"]) return SBSDKBarcodeTypeITF;
    if ([string isEqualToString:@"RSS_14"]) return SBSDKBarcodeTypeRSS14;
    if ([string isEqualToString:@"RSS_EXPANDED"]) return SBSDKBarcodeTypeRSSExpanded;
    if ([string isEqualToString:@"PDF_417"]) return SBSDKBarcodeTypePDF417;
    if ([string isEqualToString:@"QR_CODE"]) return SBSDKBarcodeTypeQRCode;
    if ([string isEqualToString:@"UPC_A"]) return SBSDKBarcodeTypeUPCA;
    if ([string isEqualToString:@"UPC_E"]) return SBSDKBarcodeTypeUPCE;
    if ([string isEqualToString:@"MSI_PLESSEY"]) return SBSDKBarcodeTypeMSIPlessey;
    return nil;
}

static inline SBSDKBarcodeDocumentType* barcodeDocumentTypeFromString(NSString* string) {
    if ([string isEqualToString:@"AAMVA"]) return SBSDKBarcodeDocumentTypeAAMVA;
    if ([string isEqualToString:@"ID_CARD_PDF_417"]) return SBSDKBarcodeDocumentTypeIDCardPDF417;
    if ([string isEqualToString:@"SEPA"]) return SBSDKBarcodeDocumentTypeSEPA;
    if ([string isEqualToString:@"MEDICAL_CERTIFICATE"]) return SBSDKBarcodeDocumentTypeMedicalCertificate;
    if ([string isEqualToString:@"BOARDING_PASS"]) return SBSDKBarcodeDocumentTypeBoardingPass;
    if ([string isEqualToString:@"DE_MEDICAL_PLAN"]) return SBSDKBarcodeDocumentTypeMedicalPlan;
    if ([string isEqualToString:@"VCARD"]) return SBSDKBarcodeDocumentTypeVCard;
    if ([string isEqualToString:@"SWISS_QR"]) return SBSDKBarcodeDocumentTypeSwissQR;
    return nil;
}

static inline NSString* stringFromBarcodeType(SBSDKBarcodeType* type) {
    if ([type.name isEqualToString:@"QRCode"]) {
        return @"QR_CODE";
    }

    NSString* result = [type.name uppercaseString];
    result = [result stringByReplacingOccurrencesOfString:@"-" withString:@"_"];
    result = [result stringByReplacingOccurrencesOfString:@" " withString:@"_"];
    return result;
}

static inline NSDictionary<NSString*, NSObject*>* jsonFromBarcodeResult(SBSDKBarcodeScannerResult *result) {

    NSMutableDictionary* x = @{
        @"type": stringFromBarcodeType(result.type),
        @"text": result.rawTextString,
    }.mutableCopy;
    return x.copy;
}

static inline NSArray<NSDictionary<NSString*, NSObject*>*>* jsonFromMappedBarcodeResults(NSArray<SBSDKUIBarcodeMappedResult *> *results) {
    NSMutableArray<NSDictionary<NSString*, NSObject*>*>* jsonResults = [[NSMutableArray alloc] init];
    for (int i = 0; i < results.count; ++i) {
        [jsonResults addObject:jsonFromBarcodeResult([results objectAtIndex:i].barcode)];
    }

    return [jsonResults copy];
}

static inline NSArray<NSDictionary<NSString*, NSObject*>*>* jsonFromBarcodeResults(NSArray<SBSDKBarcodeScannerResult *> *results) {
    NSMutableArray<NSDictionary<NSString*, NSObject*>*>* jsonResults = [[NSMutableArray alloc] init];
    for (int i = 0; i < results.count; ++i) {
        [jsonResults addObject:jsonFromBarcodeResult([results objectAtIndex:i])];
    }

    return [jsonResults copy];
}

static inline SBSDKUICameraConfiguration* extractCameraConfiguration(NSDictionary* configuration) {
    SBSDKUICameraConfiguration* cameraConfiguration = [[SBSDKUICameraConfiguration alloc] init];
    
    NSString* cameraModule = [configuration objectForKey:@"cameraModule"];
    if(!cameraModule) {
        return nil;
    }
    
    if ([cameraModule isEqualToString:@"FRONT"]) {
        cameraConfiguration.camera = SBSDKCameraDevice.defaultFrontFacingCamera;
    } else if ([cameraModule isEqualToString:@"BACK"]) {
        cameraConfiguration.camera = SBSDKCameraDevice.defaultBackFacingCamera;
    }
    
    return cameraConfiguration;
}

static inline SBSDKBarcodeMSIPlesseyChecksumAlgorithm extractPlesseyChecksumAlgorithmFromConfiguration(NSDictionary* configuration) {
    NSString* algorithm = [configuration objectForKey:@"msiPlesseyChecksumAlgorithm"];
    
    if (algorithm != nil) {
        if ([algorithm isEqualToString:@"None"]) return SBSDKBarcodeMSIPlesseyChecksumAlgorithmNone;
        if ([algorithm isEqualToString:@"Mod10"]) return SBSDKBarcodeMSIPlesseyChecksumAlgorithmMod10;
        if ([algorithm isEqualToString:@"Mod11IBM"]) return SBSDKBarcodeMSIPlesseyChecksumAlgorithmMod11IBM;
        if ([algorithm isEqualToString:@"Mod11NCR"]) return SBSDKBarcodeMSIPlesseyChecksumAlgorithmMod11NCR;
        if ([algorithm isEqualToString:@"Mod1010"]) return SBSDKBarcodeMSIPlesseyChecksumAlgorithmMod1010;
        if ([algorithm isEqualToString:@"Mod1110IBM"]) return SBSDKBarcodeMSIPlesseyChecksumAlgorithmMod1110IBM;
        if ([algorithm isEqualToString:@"Mod1110NCR"]) return SBSDKBarcodeMSIPlesseyChecksumAlgorithmMod1110NCR;
    }
    
    return SBSDKBarcodeMSIPlesseyChecksumAlgorithmMod10;
}

static inline NSArray* extractBarcodeTypesFromConfiguration(NSDictionary* configuration) {
    NSArray* barcodeFormats = [configuration objectForKey:@"barcodeFormats"];
    if (barcodeFormats && [barcodeFormats indexOfObject:@"ALL_FORMATS"] == NSNotFound) {
        NSMutableArray* machineCodeTypes = [NSMutableArray array];
        for (NSString* format in barcodeFormats) {
            SBSDKBarcodeType* type = barcodeTypeFromString(format);
            if (type != nil) {
                [machineCodeTypes addObject:type];
            }
        }
        return machineCodeTypes.copy;
    }
    return nil;
}

static inline NSArray* extractBarcodeDocumentTypesFromConfiguration(NSDictionary* configuration) {
    NSArray* documentFormats = [configuration objectForKey:@"acceptedDocumentFormats"];
    if (documentFormats) {
        NSMutableArray* outDocumentTypes = [NSMutableArray array];
        for (NSString* format in documentFormats) {
            SBSDKBarcodeDocumentType* type = barcodeDocumentTypeFromString(format);
            if (type != nil) {
                [outDocumentTypes addObject:type];
            }
        }
        return outDocumentTypes.copy;
    }
    return nil;
}

#endif /* BarcodeMapping_h */
