#include <stdio.h>
#include <stdlib.h>

#include <errno.h>
/*
#ifdef USE_MOBICORE
#include "MobiCoreDriverApi.h"
#endif
*/
#include "tlc_spay_tui.h"

#include "tl_spay_tui_msg.h"

#include "test.h"

/*
#define SECRET_IMAGE_FILE	"/data/local/tmp/knox.png"
#define WIDTH			115
#define HEIGHT			41
*/

#define SECRET_IMAGE_FILE	"/data/local/tmp/secret1.png"
#define WIDTH			437
#define HEIGHT			112

uint8_t APP_NAME[] =
    { 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x14 };

/*
extern timaTuiResult_t timaLaunchTui(
	uint8_t *app_name, 
	uint32_t app_name_len, 
	uint8_t *secret_id, 
	uint32_t secret_id_len, 
	uint8_t* nonce, 
	uint32_t nonce_len,
	bool verify,
	uint8_t min_pin_len);
*/

uint32_t load_image(
	char *file_name,
	uint8_t * image,
	uint32_t * image_len
)
{
	int size;
	uint32_t ret;

	FILE *fp = fopen(file_name, "rb");
	if (fp == NULL) {
		printf("Cannot open image file %s\n", file_name);
		return 1;
	}

	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fseek(fp, 0, SEEK_SET);

	if (size > *image_len) {
		printf("Image file size (%d) is too big!\n", size);
		fclose(fp);
		return 2;
	}

	fread(image, 1, size, fp);
	*image_len = size;
	fclose(fp);
	return 0;
}

int main(
	int argc,
	char *argv[]
)
{
/*
	uint8_t nonce[NONCE_BUFFER_SIZE];
	timaTuiResult_t pin = {0};
	timaTuiPinResult_t real_pin;

	uint8_t secret_buf[SECRET_IMAGE_BUFFER_SIZE];
	uint32_t buf_len = SECRET_IMAGE_BUFFER_SIZE;

	uint8_t secret_id[4];
*/
#if 0
	// step 1: init secret
	printf("======= INIT SECRET =============\n");
	if (read_file(SECRET_IMAGE_FILE, secret_buf, &buf_len) == 0) {
		timaTuiInitSecret(secret_buf, buf_len, WIDTH, HEIGHT);
	}

	printf("Init secret done\n");
#endif
	// step 2: launch 
/*	printf("======= LAUNCH PINPAD =============\n");
	for(int i=0; i<NONCE_BUFFER_SIZE; i++){
		nonce[i] = i;
	}

	printf("Launch PIN Pad\n");

	pin = timaLaunchTui(
			APP_NAME, sizeof(APP_NAME), 
			secret_id, 0,
			nonce, NONCE_BUFFER_SIZE, 
			true, 1);
*/

	uint8_t image[RESOURCE_BUFFER_SIZE];
	uint32_t image_len = RESOURCE_BUFFER_SIZE;

	if (argc != 2 && argc != 3) {
		printf("Usage: '%s setup|verify|resume <image_file_name>'\n",
		       argv[0]);
		return -1;
	}

	if (argc == 3) {
		load_image(argv[2], image, &image_len);
	}

	if (strcmp(argv[1], "setup") == 0) {
		//for(int i=0; i<10; i++)
		printf("Setup PIN returns: %d\n", spayTuiSetupPin());
	} else if (strcmp(argv[1], "verify") == 0) {

		uint8_t app_name[] = "ffffffff00000000000000000000001c";
		uint8_t nonce[32];

		uint8_t result[4096];
		uint32_t result_len = 4096;

		//printf("Verify PIN returns: %d\n", spayTuiAuthPin(3, app_name, strlen((char*)app_name), nonce, 32, result, &result_len, image, image_len));
		printf("Verify PIN returns: %d\n", spayTuiVerify());
	} else if (strcmp(argv[1], "resume") == 0) {
		printf("Resume test returns: %d\n", spayTuiTestResume());
	} else {
		printf("Usage: '%s setup' or '%s verify'\n", argv[0], argv[0]);
		return -1;
	}

/*
	if (pin.ret == 0){
		printf("Successfully get PIN\n");

		printf("Pin buffer length = %d\n\t", pin.buffer_len);
		for(int i=0; i<pin.buffer_len; i++){
			printf("0x%02x ", pin.buffer[i]);
		}
		printf("\n");

	} else {
		printf("Failed to get PIN: ret = %d\n", pin.ret);

		printf("Error msg: %s\n", pin.error_msg);

		return -1;
	}

	// step 3: unwrap

	printf("======= UNWRAP PIN =============\n");

	pin = timaTuiUnwrap(pin.buffer, pin.buffer_len);

	if (pin.ret == 0){
		printf("Successfully unwrap PIN\n");

		printf("Pin buffer length = %d\n\t", pin.buffer_len);
		for(int i=0; i<pin.buffer_len; i++){
			printf("0x%02x ", pin.buffer[i]);
		}
		printf("\n");

		if (pin.buffer_len != sizeof(real_pin)){
			printf("The unwrapped PIN buffer has wrong size %d\n", pin.buffer_len);
		} else {
			memcpy(&real_pin, pin.buffer, pin.buffer_len);
			printf("\n\nPin: ");
			for(int i=0; i<real_pin.pin_len; i++){
				printf("%d ", real_pin.pin[i]);
			}
			printf("\n\nNonce: ");
			for(int i=0; i<real_pin.nonce_len; i++){
				printf("0x%02x ", real_pin.nonce[i]);
			}
			printf("\n\n");
		}

	} else {
		printf("Failed to unwrap PIN: ret = %d\n", pin.ret);

		printf("%s\n", pin.error_msg);
	}

*/
	return 0;
}
