/*
 * Client : tee_pthread_matrix_mult.c
 * TA     : tee_pthread_matrix_mult_TA  (d06bb1c6-8fe1-4b6e-a787-d118f9babd8e)
 */

/* TestCase     : tee_test_pthread_multiply_matrix_simple
 * Name         : Matrix matrix multiplication simple example
 * Description  : Multiplication of two matrixes in parallel
 * Precondition : None.
 * Scenario     : 1. Main TA thread creates separate thread for each row in \
 *                   result-matrix
 *                2. Then Main TA thread waits for completion of threads' job
 *                3. Each thread calculates row in result-matrix
 *                4. After joining, Main thread checks that \
 *                   computed matrix equals to pre-computed
 * Pass Cond    : Passed if comparison with pre-computed matrix is successful.
 */

#include <stdio.h>
#include <tee_client_api.h>

static const TEEC_UUID uuid_pthread_matrix_mul =
    { 0xd06bb1c6, 0x8fe1, 0x4b6e, {0xa7,0x87,0xd1,0x18,0xf9,0xba,0xbd,0x8e} };

enum { MULTIPLY_MATRIX_SIMPLE };

static TEEC_Result tee_test(TEEC_Context *context,
                            int cmd_id,
                            const TEEC_UUID *uuid)
{
    TEEC_Result res;
    TEEC_Session session;
    uint32_t returnOrigin;

    res = TEEC_OpenSession(context, &session,
                           uuid, 0, NULL,
                           NULL, &returnOrigin);
    if (res != TEEC_SUCCESS) {
        printf("TEEC_OpenSession returned %s from %s\n",
               get_error_name(res),
               get_return_origin(returnOrigin));
        goto out;
    }

    res = TEEC_InvokeCommand(&session, cmd_id, NULL, &returnOrigin);
    if (res != TEEC_SUCCESS) {
        printf("TEEC_InvokeCommand returned %s from %s\n",
               get_error_name(res),
               get_return_origin(returnOrigin));
    }

    TEEC_CloseSession(&session);

out:
    return res;
}

int main(int argc, char **argv)
{
    (void) argc;
    (void) argv;
    TEEC_Result res;
    TEEC_Context context;

    res = TEEC_InitializeContext(NULL, &context);
    if (res != TEEC_SUCCESS) {
        printf("InitializeContext failed: %s\n", get_error_name(res));
        goto out;
    }

    res = tee_test(&context,
                   MULTIPLY_MATRIX_SIMPLE,
                   &uuid_pthread_matrix_mul);
    if (res != TEEC_SUCCESS) {
        printf("tee_test failed: %d\n", res);
    }

    TEEC_FinalizeContext(&context);

out:
    if (res != TEEC_SUCCESS) {
        printf("TEST FAILED\n");
        return 1;
    }

    printf("TEST PASSED\n");
    return 0;
}
