#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "demo_common.h"

extern IDT_COMMON_PROCESS COMMON;
extern IDT_PROCESS idtech_process;
extern IDT_DEMO_LIB_DISPLAY_MENU idtech_display_menu_from_lib;

void
_PipReader_display_device_menu();

void
_PipReader_process_device() {
    int choice;
    int r = 0;
    char str1[256] = { 0 };
    int len        = 512;

    memset(str1, 0, 256);
    IDTMSRData cardData;
    do {
        _PipReader_display_device_menu();
        //		printf("Please Input your Selection:\n");
        //		scanf("%d",&choice);
        choice = COMMON.inputSelection();
        switch (choice) {
            case 1: {
                printf(">>1. Get Firmware Version\n");
                fflush(stdout);
                r = device_getFirmwareVersion(str1);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Get Firmware Version Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                        strErr);
                } else {
                    char str2[200] = { 0 };
                    sprintf(str2, "Firmware version: %s\n", str1);
                    printf(str2);
                }
                fflush(stdout);
            }
            break;
            case 2: {
                printf(">>2. Send Command: 0x29, 0x00\n");
                fflush(stdout);
                BYTE rbbyte[512] = { 0 };
                memset(rbbyte, 0, 512);
                len = 512;

                r = device_SendDataCommandNEO(0x29, 0x00, NULL, 0, rbbyte, &len);

                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Do device_SendDataCommand(), failed! ErrorCode:0x%02x ,Info: %s ----- \n", r,
                        strErr);
                } else {
                    char str3[1024] = { 0 };
                    memset(str3, 0, 1024);
                    COMMON.convertBytesIntoHexStr(rbbyte, len, 0, str3);
                    printf("response code : %s\n", str3);
                    int i;
                    for (i = 0; i < len; i++) {
                        printf("%c", rbbyte[i]);
                    }
                    printf("\n");
                }
                fflush(stdout);
            }
            break;
            case 3: {
                printf(">>3. Get Serial Number\n");
                fflush(stdout);
                r = config_getSerialNumber(str1);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Get Serial Number Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                        strErr);
                } else {
                    char str2[200] = { 0 };
                    sprintf(str2, "Serial Number: %s\n", str1);
                    printf(str2);
                }
                fflush(stdout);
            }
            break;
            case 4: {
                printf(">>4. Ping Device\n");
                fflush(stdout);
                r = device_pingDevice();
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Ping Device Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Ping Device Succeeded\n");
                }
                fflush(stdout);
            }
            break;
            case 5:
                printf(">>5. Pass Through On\n");
                fflush(stdout);
                r = device_enablePassThrough(1);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Pass Through On Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Pass Through On Succeeded\n");
                }
                fflush(stdout);
                break;
            case 6:
                printf(">>6. Pass Through Off\n");
                fflush(stdout);
                r = device_enablePassThrough(0);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Pass Through Off Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Pass Through Off Succeeded\n");
                }
                fflush(stdout);
                break;
            case 7:
                printf(">>7. Set Burst On\n");
                fflush(stdout);
                r = device_setBurstMode(1);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Set Burst On Failed! ErrorCode:0x%02x, Info: %s ----- \n",
                        r, strErr);
                } else {
                    printf("Set Burst On Succeeded\n");
                }
                fflush(stdout);
                break;
            case 8:
                printf(">>8. Set Burst Off\n");
                fflush(stdout);
                r = device_setBurstMode(0);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Set Burst Off Failed! ErrorCode:0x%02x, Info: %s ----- \n",
                        r, strErr);
                } else {
                    printf("Set Burst Off Succeeded\n");
                }
                fflush(stdout);
                break;

            case 9:
                printf(">>9. Set Auto Poll On\n");
                fflush(stdout);
                r = device_setPollMode(0);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Set Auto Poll On Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Set Auto Poll On Succeeded\n");
                }
                fflush(stdout);
                break;
            case 10:
                printf(">>10. Poll On Demand\n");
                fflush(stdout);
                r = device_setPollMode(1);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Poll On Demand Failed! ErrorCode:0x%02x, Info: %s ----- \n",
                        r, strErr);
                } else {
                    printf("Set Poll On Demand Succeeded\n");
                }
                fflush(stdout);
                break;
            case 11:
                printf(">>11. Set Merchant Record\n");
                fflush(stdout);
                r = device_setMerchantRecord(1, 1, "pass.com.pronto.id-tech.demo", null);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Set Merchant Record Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Set Merchant Record Succeeded\n");
                }
                fflush(stdout);
                break;
            case 12:
                printf(">>12. Get Merchant Record\n");
                fflush(stdout);
                BYTE record[0x63];
                memset(record, 0, 0x63);
                r = device_getMerchantRecord(1, record);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Get Merchant Record Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Get Merchant Record Succeeded\n");
                    int i;
                    printf("Record:\n");
                    for (i = 0; i < 0x63; i++) {
                        printf("%02X", record[i]);
                    }
                    printf("\n");
                }
                fflush(stdout);
                break;
            case 13:
                printf(">>13. Get Transaction Results\n");
                fflush(stdout);
                r = device_getTransactionResults(&cardData);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Do device_SendDataCommand(), failed! ErrorCode:0x%02x ,Info: %s ----- \n", r,
                        strErr);
                } else {
                    COMMON.printMSRData(&cardData);
                }
                fflush(stdout);
                break;
            case 14: {
                printf(">>14. Set Collector ID\n");
                fflush(stdout);
                BYTE rbbyte[512] = { 0 };
                memset(rbbyte, 0, 512);
                len = 512;

                BYTE tlv14[200];
                int tlvLen14 = 200;
                char * str14 =
                  "FFE4018EDFEE3B0405D13A3DDFEE3C00DFEE3D00DFEF2500DFED0100DFED02050000000001DFED030101DFED040101DFED050101DFED060100DFED070100DFED27010DDFED3F0100DFED490100DFEF770100";
                COMMON.convertHStrIntoHex(str14, tlv14, &tlvLen14);

                r = device_SendDataCommandNEO(0x04, 0x03, tlv14, tlvLen14, rbbyte, &len);

                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Set Collector ID failed! ErrorCode:0x%02x ,Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Set Collector ID Succeeded\n");
                }
                fflush(stdout);
            }
            break;
            case 15: {
                printf(">>15. Get Collector ID\n");
                fflush(stdout);
                BYTE rbbyte[512] = { 0 };
                memset(rbbyte, 0, 512);
                len = 512;

                BYTE tlv15[] = { 0xFF, 0xE4, 0x01, 0x8E };
                r = device_SendDataCommandNEO(0x03, 0x06, tlv15, 4, rbbyte, &len);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Get Collector ID failed! ErrorCode:0x%02x ,Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Get Collector ID Succeeded\nCollector ID: ");
                    COMMON.printBytes(rbbyte, len);
                    printf("\n");
                    COMMON.printTLV(rbbyte, len);
                }
                fflush(stdout);
            }
            break;
            case 16: {
                printf(">>16. Set VAS Private Key\n");
                fflush(stdout);
                BYTE rbbyte[512] = { 0 };
                memset(rbbyte, 0, 512);
                len = 512;

                BYTE tlv15[200];
                int tlvLen15 = 200;
                char * str15 = "F5368708933920553B7B9FFB16AEED9C77D5BFD9662AF149A6B9F965B73F0CCA";
                COMMON.convertHStrIntoHex(str15, tlv15, &tlvLen15);

                r = device_SendDataCommandNEO(0xC7, 0x66, tlv15, tlvLen15, rbbyte, &len);

                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Set Vas Private Key failed! ErrorCode:0x%02x ,Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Set Vas Private Key Succeeded\n");
                }
                fflush(stdout);
            }
            break;
            case 17: {
                printf(">>17. Set SmartTap LTPK\n");
                fflush(stdout);
                BYTE rbbyte[512] = { 0 };
                memset(rbbyte, 0, 512);
                len = 512;

                BYTE tlv16[200];
                int tlvLen16 = 200;
                char * str16 = "0000000AF5368708933920553B7B9FFB16AEED9C77D5BFD9662AF149A6B9F965B73F0CCA";
                COMMON.convertHStrIntoHex(str16, tlv16, &tlvLen16);

                r = device_SendDataCommandNEO(0xC7, 0x65, tlv16, tlvLen16, rbbyte, &len);

                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Set SmartTap LTPK failed! ErrorCode:0x%02x ,Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Set SmartTap LTPK Succeeded\n");
                }
                fflush(stdout);
            }
            break;
                #if 0
            case 18:
                printf(">>18. Update Firmware\n");
                fflush(stdout);
                char firmware_file_name[50];
                memset(firmware_file_name, 0, 50);
                printf("Please enter the firmware file name (Ex. Kiosk III NEO v1.10.064.S_ENC_USBHID.txt):\n");
                fflush(stdout);
                fgets(firmware_file_name, 50, stdin);
                int i;
                for (i = 49; i >= 0; i--) {
                    if (firmware_file_name[i] == '\n' || firmware_file_name[i] == '\r') {
                        firmware_file_name[i] = '\0';
                        break;
                    }
                }
                printf("Firmware File Name: %s\n", firmware_file_name);
                FILE * fp;
                if (NULL == (fp = fopen(firmware_file_name, "r"))) {
                    printf("Could not open file %s\n", firmware_file_name);
                    break;
                }
                fflush(stdout);
                char firmwareData[_FIRMWARE_BUF_LEN];
                memset(firmwareData, 0, _FIRMWARE_BUF_LEN);
                int fw_lines = 0;
                int idx      = 0;
                char * line  = firmware_file_name;
                char temp[_FIRMWARE_CMD_LEN];
                while (!feof(fp) && strcmp(line, "END>")) {
                    if (idx >= _FIRMWARE_BUF_LEN) {
                        break;
                    }
                    memset(temp, 0, _FIRMWARE_CMD_LEN);
                    fgets(temp, _FIRMWARE_CMD_LEN, fp);
                    for (i = (_FIRMWARE_CMD_LEN) -1; i >= 0; i--) {
                        if (temp[i] == '\n' || temp[i] == '\r') {
                            temp[i] = '\0';
                            break;
                        }
                    }
                    line = temp;
                    strcpy(&(firmwareData[idx]), temp);
                    fw_lines++;
                    idx += strlen(temp) + 1;
                }
                fclose(fp);
                if (idx >= _FIRMWARE_BUF_LEN) {
                    printf("Not enough buffer\n");
                    fflush(stdout);
                    break;
                }
                printf("\033[1;31mUpdating firmware, please do not unplug the reader or exit this demo...\033[0m\n");
                fflush(stdout);
                //				printf("Firmware Update, please do not unplug the reader or close this program...\n");
                r = device_updateFirmware(firmwareData, idx, NULL, 0, NULL, 0);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    if (r == IDG_P2_STATUS_CODE_FW_INIT_SUCCESS) {
                        //						printf("Initialize Firmware Update succeeded, please re-select the device after reboot, and do Update Firmware again.\n");
                        if (device_getCurrentDeviceType() == IDT_DEVICE_KIOSK_III_S) {
                            printf(
                                "\033[1;31mInitialize Firmware Update succeeded, please re-select the same device through Device Select Options menu, and do Update Firmware again.\033[0m\n");
                        } else {
                            printf(
                                "\033[1;31mInitialize Firmware Update succeeded, please do Update Firmware again.\033[0m\n");
                        }
                        printf(
                            "\033[1;31mWarning: Please do NOT close this program before firmware update is done.\033[0m\n");
                    } else {
                        //						printf("Firmware Update failed!\n");
                        printf("\033[1;31mFirmware Update failed!\033[0m\n");
                        printf("Error code: 0x%04X\n", r);
                    }
                } else {
                    //					printf("Firmware Update succeeded.\n");
                    printf(
                        "\033[1;31mFirmware Update succeeded.  Please re-select a device through Device Select Options menu.\033[0m\n");
                }
                fflush(stdout);
                break;
                #endif /* if 0 */
            case 0:
                printf(">>0.Back To Main Menu\n");
                fflush(stdout);
                break;
        }
    } while (choice != 0);
    // #ifdef WIN32
    if (choice == 0) {
//        idtech_process.pProcess_function_list();
        return;
    }
    // #endif
} /* _PipReader_process_device */

void
_PipReader_display_device_menu() {
    idtech_display_menu_from_lib.pDisplay_Menu_current = _PipReader_display_device_menu;
    printf("\t\t********** Device Options [Pip Reader]***********\n");
    printf("\t\t0.  Back To Main Menu\n");
    printf("\t\t1.  Get Firmware Version\n");
    printf("\t\t2.  Send Data Command\n");
    printf("\t\t3.  Get Serial Number\n");
    printf("\t\t4.  Ping Device\n");
    printf("\t\t5.  Enable Passthrough\n");
    printf("\t\t6.  Disable Passthrough\n");
    printf("\t\t7.  Burst Mode ON\n");
    printf("\t\t8.  Burst Mode OFF\n");
    printf("\t\t9.  Auto Poll\n");
    printf("\t\t10. Poll On Demand\n");
    printf("\t\t11. Set Merchant Record\n");
    printf("\t\t12. Get Merchant Record\n");
    printf("\t\t13. Get Transaction Results\n");
    printf("\t\t14. Set Collector ID\n");
    printf("\t\t15. Get Collector ID\n");
    printf("\t\t16. Set VAS Private Key\n");
    printf("\t\t17. Set SmartTap LTPK\n");
    //	printf("\t\t18. Update Firmware (Need to run twice)\n");
    printf("\t\t************************************************\n");
    fflush(stdout);
}
