/* BEGIN_HEADER */
#include "../library/psa_crypto_its.h"

#include "psa_helpers.h"

/* Internal definitions of the implementation, copied for the sake of
 * some of the tests and of the cleanup code. */
#define PSA_ITS_STORAGE_PREFIX ""
#define PSA_ITS_STORAGE_FILENAME_PATTERN "%08lx%08lx"
#define PSA_ITS_STORAGE_SUFFIX ".psa_its"
#define PSA_ITS_STORAGE_FILENAME_LENGTH         \
    ( sizeof( PSA_ITS_STORAGE_PREFIX ) - 1 + /*prefix without terminating 0*/ \
      16 + /*UID (64-bit number in hex)*/                               \
      sizeof( PSA_ITS_STORAGE_SUFFIX ) - 1 + /*suffix without terminating 0*/ \
      1 /*terminating null byte*/ )
#define PSA_ITS_STORAGE_TEMP \
    PSA_ITS_STORAGE_PREFIX "tempfile" PSA_ITS_STORAGE_SUFFIX
static void psa_its_fill_filename( psa_storage_uid_t uid, char *filename )
{
    /* Break up the UID into two 32-bit pieces so as not to rely on
     * long long support in snprintf. */
    mbedtls_snprintf( filename, PSA_ITS_STORAGE_FILENAME_LENGTH,
                      "%s" PSA_ITS_STORAGE_FILENAME_PATTERN "%s",
                      PSA_ITS_STORAGE_PREFIX,
                      (unsigned long) ( uid >> 32 ),
                      (unsigned long) ( uid & 0xffffffff ),
                      PSA_ITS_STORAGE_SUFFIX );
}

/* Maximum uid used by the test, recorded so that cleanup() can delete
 * all files. 0xffffffffffffffff is always cleaned up, so it does not
 * need to and should not be taken into account for uid_max. */
static psa_storage_uid_t uid_max = 0;

static void cleanup( void )
{
    char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
    psa_storage_uid_t uid;
    for( uid = 0; uid < uid_max; uid++ )
    {
        psa_its_fill_filename( uid, filename );
        remove( filename );
    }
    psa_its_fill_filename( (psa_storage_uid_t)( -1 ), filename );
    remove( filename );
    remove( PSA_ITS_STORAGE_TEMP );
    uid_max = 0;
}

static psa_status_t psa_its_set_wrap( psa_storage_uid_t uid,
                                      uint32_t data_length,
                                      const void *p_data,
                                      psa_storage_create_flags_t create_flags )
{
    if( uid_max != (psa_storage_uid_t)( -1 ) && uid_max < uid )
        uid_max = uid;
    return( psa_its_set( uid, data_length, p_data, create_flags ) );
}

/* END_HEADER */

/* BEGIN_DEPENDENCIES
 * depends_on:MBEDTLS_PSA_ITS_FILE_C
 * END_DEPENDENCIES
 */

/* BEGIN_CASE */
void set_get_remove( int uid_arg, int flags_arg, data_t *data )
{
    psa_storage_uid_t uid = uid_arg;
    uint32_t flags = flags_arg;
    struct psa_storage_info_t info;
    unsigned char *buffer = NULL;
    size_t ret_len = 0;

    ASSERT_ALLOC( buffer, data->len );

    PSA_ASSERT( psa_its_set_wrap( uid, data->len, data->x, flags ) );

    PSA_ASSERT( psa_its_get_info( uid, &info ) );
    TEST_ASSERT( info.size == data->len );
    TEST_ASSERT( info.flags == flags );
    PSA_ASSERT( psa_its_get( uid, 0, data->len, buffer, &ret_len ) );
    ASSERT_COMPARE( data->x, data->len, buffer, ret_len );

    PSA_ASSERT( psa_its_remove( uid ) );

exit:
    mbedtls_free( buffer );
    cleanup( );
}
/* END_CASE */

/* BEGIN_CASE */
void set_overwrite( int uid_arg,
                    int flags1_arg, data_t *data1,
                    int flags2_arg, data_t *data2 )
{
    psa_storage_uid_t uid = uid_arg;
    uint32_t flags1 = flags1_arg;
    uint32_t flags2 = flags2_arg;
    struct psa_storage_info_t info;
    unsigned char *buffer = NULL;
    size_t ret_len = 0;

    ASSERT_ALLOC( buffer, MAX( data1->len, data2->len ) );

    PSA_ASSERT( psa_its_set_wrap( uid, data1->len, data1->x, flags1 ) );
    PSA_ASSERT( psa_its_get_info( uid, &info ) );
    TEST_ASSERT( info.size == data1->len );
    TEST_ASSERT( info.flags == flags1 );
    PSA_ASSERT( psa_its_get( uid, 0, data1->len, buffer, &ret_len ) );
    ASSERT_COMPARE( data1->x, data1->len, buffer, ret_len );

    PSA_ASSERT( psa_its_set_wrap( uid, data2->len, data2->x, flags2 ) );
    PSA_ASSERT( psa_its_get_info( uid, &info ) );
    TEST_ASSERT( info.size == data2->len );
    TEST_ASSERT( info.flags == flags2 );
    ret_len = 0;
    PSA_ASSERT( psa_its_get( uid, 0, data2->len, buffer, &ret_len ) );
    ASSERT_COMPARE( data2->x, data2->len, buffer, ret_len );

    PSA_ASSERT( psa_its_remove( uid ) );

exit:
    mbedtls_free( buffer );
    cleanup( );
}
/* END_CASE */

/* BEGIN_CASE */
void set_multiple( int first_id, int count )
{
    psa_storage_uid_t uid0 = first_id;
    psa_storage_uid_t uid;
    char stored[40];
    char retrieved[40];
    size_t ret_len = 0;

    memset( stored, '.', sizeof( stored ) );
    for( uid = uid0; uid < uid0 + count; uid++ )
    {
        mbedtls_snprintf( stored, sizeof( stored ),
                          "Content of file 0x%08lx", (unsigned long) uid );
        PSA_ASSERT( psa_its_set_wrap( uid, sizeof( stored ), stored, 0 ) );
    }

    for( uid = uid0; uid < uid0 + count; uid++ )
    {
        mbedtls_snprintf( stored, sizeof( stored ),
                          "Content of file 0x%08lx", (unsigned long) uid );
        PSA_ASSERT( psa_its_get( uid, 0, sizeof( stored ), retrieved, &ret_len ) );
        ASSERT_COMPARE( retrieved, ret_len,
                        stored, sizeof( stored ) );
        PSA_ASSERT( psa_its_remove( uid ) );
        TEST_ASSERT( psa_its_get( uid, 0, 0, NULL, NULL ) ==
                     PSA_ERROR_DOES_NOT_EXIST );
    }

exit:
    cleanup( );
}
/* END_CASE */

/* BEGIN_CASE */
void nonexistent( int uid_arg, int create_and_remove )
{
    psa_storage_uid_t uid = uid_arg;
    struct psa_storage_info_t info;

    if( create_and_remove )
    {
        PSA_ASSERT( psa_its_set_wrap( uid, 0, NULL, 0 ) );
        PSA_ASSERT( psa_its_remove( uid ) );
    }

    TEST_ASSERT( psa_its_remove( uid ) == PSA_ERROR_DOES_NOT_EXIST );
    TEST_ASSERT( psa_its_get_info( uid, &info ) ==
                 PSA_ERROR_DOES_NOT_EXIST );
    TEST_ASSERT( psa_its_get( uid, 0, 0, NULL, NULL ) ==
                 PSA_ERROR_DOES_NOT_EXIST );

exit:
    cleanup( );
}
/* END_CASE */

/* BEGIN_CASE */
void get_at( int uid_arg, data_t *data,
             int offset, int length_arg,
             int expected_status )
{
    psa_storage_uid_t uid = uid_arg;
    unsigned char *buffer = NULL;
    psa_status_t status;
    size_t length = length_arg >= 0 ? length_arg : 0;
    unsigned char *trailer;
    size_t i;
    size_t ret_len = 0;

    ASSERT_ALLOC( buffer, length + 16 );
    trailer = buffer + length;
    memset( trailer, '-', 16 );

    PSA_ASSERT( psa_its_set_wrap( uid, data->len, data->x, 0 ) );

    status = psa_its_get( uid, offset, length_arg, buffer, &ret_len );
    TEST_ASSERT( status == (psa_status_t) expected_status );
    if( status == PSA_SUCCESS )
        ASSERT_COMPARE( data->x + offset, (size_t) length_arg,
                        buffer, ret_len );
    for( i = 0; i < 16; i++ )
        TEST_ASSERT( trailer[i] == '-' );
    PSA_ASSERT( psa_its_remove( uid ) );

exit:
    mbedtls_free( buffer );
    cleanup( );
}
/* END_CASE */
