#include "test_TA_math.h"
#include <tee_internal_api.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define EPS                                                0.00001

#define DO_TEST_TWO_ARG(fun, arg1, arg2, comp, result)     if (fun(arg1, arg2) < comp - EPS && fun(arg1, arg2) > EPS + comp) { \
                                                               result = TEE_ERROR_GENERIC; \
                                                           }

#define DO_TEST_ONE_ARG(fun, arg1, comp, result)           if (fun(arg1) < comp - EPS && fun(arg1) > EPS + comp) { \
                                                               result = TEE_ERROR_GENERIC; \
                                                           }

TEE_Result TA_CreateEntryPoint(void)
{
    return TEE_SUCCESS;
}

void TA_DestroyEntryPoint(void)
{
}

TEE_Result TA_OpenSessionEntryPoint(uint32_t paramTypes,
    TEE_Param params[4], void **sessionContext)
{
    (void) paramTypes;
    (void) params;
    (void) sessionContext;

    return TEE_SUCCESS;
}

void TA_CloseSessionEntryPoint(void *sessionContext)
{
    (void) sessionContext;
}


TEE_Result TA_InvokeCommandEntryPoint(void *sessionContext,
    uint32_t commandID, uint32_t paramTypes, TEE_Param params[4])
{
    (void) sessionContext;
    (void) commandID;
    (void) paramTypes;
    (void) params;
    TEE_Result result = TEE_SUCCESS;

    int abs_in[] = {3, -3};
    int abs_out[] = {3, 3};

    double doub_in[] = {3.3, -3.3};
    double pow_out[] = {35.937, 118.5921};
    double fabs_out[] = {3.3, 3.3};

    double sqrt_in[] = {10.89, 4.48};
    double sqrt_out[] = {3.3, 2.2};

    double round_in[] = {0.5, -0.5};
    double round_out[] = {1, -1};

    DO_TEST_ONE_ARG(abs, abs_in[0], abs_out[0], result);
    DO_TEST_ONE_ARG(abs, abs_in[1], abs_out[1], result);

    DO_TEST_TWO_ARG(pow,  doub_in[0], 3, pow_out[0], result);
    DO_TEST_TWO_ARG(pow,  doub_in[1], 4, pow_out[1], result);

    DO_TEST_ONE_ARG(sqrt, sqrt_in[0], sqrt_out[0], result);
    DO_TEST_ONE_ARG(sqrt, sqrt_in[1], sqrt_out[1], result);

    DO_TEST_ONE_ARG(fabs, doub_in[0], fabs_out[0], result);
    DO_TEST_ONE_ARG(fabs, doub_in[1], fabs_out[1], result);

    DO_TEST_ONE_ARG(round, round_in[0], round_out[0], result);
    DO_TEST_ONE_ARG(round, round_in[1], round_out[1], result);

    return result;
}
