/**
 * @file
 * @brief Test Persistent Object API, base functionality
 * @copyright (C) 2019, Samsung Electronics Co., Ltd.
 */

#include "test_TA_po_routine.h"
#include <stdio.h>
#include <string.h>

#define NAME_OF_OBJECT "test_object"
#define INIT_DATA "this data should be written when PO create "
#define WRITE_DATA "and this data write after create"

TEE_Result create_po(void)
{
    TEE_Result ret;
    TEE_ObjectHandle object;
    uint32_t flags;

    printf("start %s\n", __FUNCTION__);

    flags = TEE_DATA_FLAG_ACCESS_READ
          | TEE_DATA_FLAG_ACCESS_WRITE
          | TEE_DATA_FLAG_ACCESS_WRITE_META
          | TEE_DATA_FLAG_SHARE_READ
          | TEE_DATA_FLAG_SHARE_WRITE
          | TEE_DATA_FLAG_OVERWRITE;

    ret = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE,
                                     (void *)NAME_OF_OBJECT,
                                     strlen(NAME_OF_OBJECT),
                                     flags,
                                     TEE_HANDLE_NULL,
                                     (void *)INIT_DATA,
                                     strlen(INIT_DATA),
                                     &object);
    if (ret) {
        printf("TEE_CreatePersistentObject failed with error 0x%x.\n", ret);
        return ret;
    }

    TEE_CloseObject(object);

    printf("end %s\n", __FUNCTION__);

    return ret;
}

TEE_Result write_po(void)
{
    TEE_Result ret;
    TEE_ObjectHandle object;
    uint32_t flags;

    printf("start %s\n", __FUNCTION__);

    flags = TEE_DATA_FLAG_ACCESS_WRITE;

    ret = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
                                   (void *)NAME_OF_OBJECT,
                                   strlen(NAME_OF_OBJECT),
                                   flags,
                                   &object);
    if (ret) {
        printf("TEE_OpenPersistentObject failed error 0x%x.\n", ret);
        return ret;
    }

    ret = TEE_SeekObjectData(object, 0, TEE_DATA_SEEK_END);
    if (ret) {
        printf("TEE_SeekObjectData failed error 0x%x.\n", ret);
        TEE_CloseObject(object);
        return ret;
    }

    ret = TEE_WriteObjectData(object, (void *)WRITE_DATA, strlen(WRITE_DATA));
    if (ret) {
        printf("TEE_WriteObjectData failed to write %zd bytes, error 0x%x.\n",
               strlen(WRITE_DATA), ret);
    }

    TEE_CloseObject(object);

    printf("end %s\n", __FUNCTION__);

    return ret;
}

TEE_Result read_po(void)
{
    TEE_Result ret;
    TEE_ObjectHandle object;
    uint32_t flags;
    uint32_t out_len;
    char data[256] = {};

    printf("start %s\n", __FUNCTION__);

    flags = TEE_DATA_FLAG_ACCESS_READ;

    ret = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
                                   (void *)NAME_OF_OBJECT,
                                   strlen(NAME_OF_OBJECT),
                                   flags,
                                   &object);
    if (ret) {
        printf("TEE_OpenPersistentObject failed error 0x%x.\n", ret);
        return ret;
    }

    ret = TEE_ReadObjectData(object, (void *)data, sizeof(data), &out_len);
    if (ret) {
        printf("TEE_ReadObjectData failed to read %zd bytes, error 0x%x.\n",
               strlen(INIT_DATA) + strlen(WRITE_DATA), ret);
    }

    printf("PO data len = %d [%s]\n", out_len, data);

    TEE_CloseObject(object);

    printf("end %s\n", __FUNCTION__);

    return ret;
}

TEE_Result delete_po(void)
{
    TEE_Result ret;
    TEE_ObjectHandle object;
    uint32_t flags;

    printf("start %s\n", __FUNCTION__);

    flags = TEE_DATA_FLAG_ACCESS_WRITE_META;

    ret = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
                                   (void *)NAME_OF_OBJECT,
                                    strlen(NAME_OF_OBJECT),
                                   flags,
                                   &object);
    if (ret) {
        printf("TEE_OpenPersistentObject failed error 0x%x.\n", ret);
        return ret;
    }

    ret = TEE_CloseAndDeletePersistentObject1(object);
    if (ret) {
        printf("TEE_CloseAndDeletePersistentObject failed error 0x%x.\n", ret);
        return ret;
    }

    printf("end %s\n", __FUNCTION__);

    return ret;
}
