#include <tee_internal_api.h>
#include <unistd.h>
#include <stdio.h>
#include <arithmetics_common.h>


typedef struct {
    TEE_BigInt* bn;
    uint32_t bnSize;
    uint32_t confidenceLevel;
    int32_t result;
    uint32_t calling_pid;
} FLATEN_PRIME_DETECT_st;

int32_t TEE_BigIntIsProbablePrime(const TEE_BigInt* op, uint32_t confidenceLevel)
{
    MB_LOGD ("Entering TEE_BigIntIsProbablePrime \n");

    CHECK_IN_PARAM(op, MPI_size, ID_TEE_BigIntIsProbablePrime); /* pointer */
    CHECK_IN_PARAM(op, BIGNUMBER_MEMORY_SIZE(op), ID_TEE_BigIntIsProbablePrime); /* BN */

    TEE_Result ret;
    uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_MEMREF_INOUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
    TEE_Param params[4];
    uint32_t ret_origin;
    FLATEN_PRIME_DETECT_st serialized_params;

    /* Check for TA_OpenSession & Open, if not exist */
    ret = check_gpcp_session();
    if(ret != TEE_SUCCESS) {
        MB_LOGD("GPCP_Check-session returned %d\n", ret);
        TEE_Panic(ID_TEE_DigestDoFinal);
    }

    serialized_params.bn = (TEE_BigInt*)op;
    serialized_params.bnSize = BIGNUMBER_MEMORY_SIZE(op);
    serialized_params.confidenceLevel = confidenceLevel;
    serialized_params.calling_pid = getpid();

    params[1].memref.buffer = &serialized_params;
    params[1].memref.size = sizeof(serialized_params);
    MB_LOGD("Invoke TEE_InvokeTACommand to gpcp \n");

    ret = Get_InvokeTACommand_Callback()(gpcp_session, TEE_TIMEOUT_INFINITE, GET_FUNC_ID( BigIntIsProbablePrime, GPCP), param_types, params, &ret_origin);

    MB_LOGD("InterTA call to GPCP returned %x\n", ret);

    if(ret == TEE_ERROR_TARGET_DEAD) {
        TEE_Panic(ID_TEE_DigestDoFinal);
    }

    MB_LOGD("TEE_BigIntIsProbablePrime Succeed \n");

    return serialized_params.result;
}

