#include "test_common.h"

CK_UTF8CHAR *new_user_pin = "22222222";
CK_UTF8CHAR *new_so_pin = "88888888";
CK_UTF8CHAR *sopin = NULL;
CK_UTF8CHAR *userpin = NULL;

//CK_UTF8CHAR prompt_and_pin_buf[80];

int
main(int argc, char *argv[]){
	CK_RV rc;
	CK_FLAGS flags = 0;
	CK_SESSION_HANDLE sess;
	int i;

	printf("Login test\n");
	for (i=1; i<argc; i++) {
		if (strcmp("-api", argv[i]) == 0) {
			++i;
			api_path = argv[i];
		} else if (strcmp("-user_pin", argv[i]) == 0) {
			++i;
			user_pin = argv[i];
		}
	}
	/* Load the PKCS11 library */
	rc = init(api_path, &funcs, NULL);
	if (rc != CKR_OK) {
		printf("init failed\n");
		return rc;
	}

	rc = get_slot_list(funcs, 
                    &SlotList, 
                    &SlotCount);
	if (rc != CKR_OK) {
		printf("get_slot_list failed, rc = 0x%x\n", rc );
		return rc;
	}
	rc = find_slot_with_token(funcs, 
                           SlotList, 
                           SlotCount, 
                           &SlotId);
	if (rc != CKR_OK) {
		printf("find_slot_with_token failed, rc = 0x%x\n", rc );
		return rc;
	}

	// Display the current token and slot info 
	rc = display_slot_info(funcs, SlotId);
	if (rc != CKR_OK) {
		printf("display slot info failed\n");
		return rc;
	}

	rc = display_token_info(funcs, SlotId);
	if (rc != CKR_OK) {
		printf("display_token_info failed\n");
		return rc;
	}

	flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
	rc = funcs->C_OpenSession( SlotId, flags, NULL, NULL, &sess );
	if (rc != CKR_OK) {
		printf("C_OpenSession failed, rc = 0x%x\n", rc );
		return rc;
	}
	printf("C_OpenSession success\n");

	userpin = user_pin;
	sopin = so_pin;

		rc = funcs->C_Login(sess, CKU_SO, sopin, strlen(sopin));
		if (rc != CKR_OK) {
			printf("C_Login failed, rc = 0x%x\n", rc );
			return rc;
		}
		printf("C_Login (CKU_SO) success\n");

		rc = funcs->C_InitPIN(sess, userpin, strlen(userpin));
		if (rc != CKR_OK) {
			printf("C_InitPIN failed, rc = 0x%x\n", rc );
			return rc;
		}
		printf("C_InitPIN success\n");

		rc = funcs->C_SetPIN(sess, sopin, strlen(sopin), 
			new_so_pin, strlen(new_so_pin));
		if (rc != CKR_OK) {
			printf("C_SetPIN failed, rc = 0x%x\n", rc );
			return rc;
		}
		printf("C_SetPIN (CKU_SO) success\n");

		rc = funcs->C_SetPIN(sess, 
			new_so_pin, strlen(new_so_pin), 
			sopin, strlen(sopin));
		if (rc != CKR_OK) {
			printf("C_SetPIN failed, rc = 0x%x\n", rc );
			return rc;
		}
		printf("C_SetPIN back (CKU_SO) success\n");

		rc = funcs->C_Logout(sess);
		if (rc != CKR_OK) {
			printf("C_Logout failed, rc = 0x%x\n", rc );
			return rc;
		}
		printf("C_Logout (CKU_SO) success\n");

		rc = funcs->C_Login(sess, CKU_USER, userpin, strlen(userpin));
		if (rc != CKR_OK) {
			printf("C_Login failed, rc = 0x%x\n", rc );
			return rc;
		}
		printf("C_Login (CKU_USER) success\n");

		rc = funcs->C_SetPIN(sess, userpin, strlen(userpin), 
			new_user_pin, strlen(new_user_pin));
		if (rc != CKR_OK) {
			printf("C_SetPIN failed, rc = 0x%x\n", rc );
			return rc;
		}
		printf("C_SetPIN (CKU_USER) success\n");

		rc = funcs->C_SetPIN(sess, 
			new_user_pin, strlen(new_user_pin), 
			userpin, strlen(userpin));
		if (rc != CKR_OK) {
			printf("C_SetPIN failed, rc = 0x%x\n", rc );
			return rc;
		}
		printf("C_SetPIN back (CKU_USER) success\n");

		rc = funcs->C_Logout(sess);
		if (rc != CKR_OK) {
			printf("C_Logout failed, rc = 0x%x\n", rc );
			return rc;
		}
		printf("C_Logout (CKU_USER) success\n");

	rc = funcs->C_CloseSession(sess);
	if (rc != CKR_OK) {
		printf("C_CloseSession failed, rc = 0x%x\n", rc );
		return rc;
	}
	printf("C_CloseSession success\n");
	printf("Login test SUCCESS\n");
	return CKR_OK;
}
