
/** @file  tst_psMetadata_06.c
*
*  @brief Test driver for psMetadata functions
*
*  This test driver contains the following tests for psMetadata:
*     Test A - Allocate metadata and items
*     Test B - Add leaf node on top of existing leaf node
*     Test C - Add leaf node to existing folder node
*     Test D - Add folder node on top of existing leaf node
*     Test E - Free psMetadata
*
*  @author  Ross Harman, MHPCC
*
*  @version $Revision: 1.8 $  $Name: not supported by cvs2svn $
*  @date  $Date: 2005-02-03 00:54:12 $
*
*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
*
*/

#include <string.h>
#include "pslib.h"
#include "psTest.h"

static void printMetadataItem(psMetadataItem *metadataItem)
{
    printf("Key Name: %8s  ", metadataItem->name);
    printf("Key pType: %2d  ", metadataItem->pType);
    printf("Key mdType: %2d  ", metadataItem->type);

    switch (metadataItem->type) {
    case PS_META_LIST:
        printf("Key Value: %17c", ' ');
        break;
    case PS_META_PRIMITIVE:
        switch(metadataItem->pType) {
        case PS_TYPE_BOOL:
            printf("Key Value: %15d  ", metadataItem->data.B);
            break;
        case PS_TYPE_S32:
            printf("Key Value: %15d  ", metadataItem->data.S32);
            break;
        case PS_TYPE_F32:
            printf("Key Value: %15.3f  ", metadataItem->data.F32);
            break;
        case PS_TYPE_F64:
            printf("Key Value: %15.3f  ", metadataItem->data.F64);
            break;
        default:
            printf("Bad type: %d ", metadataItem->pType);
        }
        break;
    case PS_META_STR:
        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
        break;
    default:
        printf("Bad type: %d ", metadataItem->type);
    }
    printf("Key Comment: %s\n", metadataItem->comment);
}


psS32 main( psS32 argc, char* argv[] )
{
    psMetadataItem *item1a = NULL;
    psMetadataItem *item1b = NULL;
    psMetadataItem *item1c = NULL;
    psMetadataItem *item2a = NULL;
    psMetadataItem *item2b = NULL;
    psMetadata *metadata = NULL;


    // Test A - Allocate metadata and items
    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata and items");
    item1a = psMetadataItemAlloc("myItem1", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
    item1b = psMetadataItemAlloc("myItem1", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 111);
    item1c = psMetadataItemAlloc("myItem1", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 222);
    item2a = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 333);
    item2b = psMetadataItemAlloc("myItem2", PS_TYPE_PTR, PS_META_LIST, "I am a folder node", NULL);
    metadata = psMetadataAlloc();
    printMetadataItem(item1a);
    printMetadataItem(item1b);
    printMetadataItem(item1c);
    printMetadataItem(item2a);
    printMetadataItem(item2b);
    printFooter(stdout, "psMetadata", "Test A - Allocate metadata and items", true);


    // Test B - Add leaf node on top of existing leaf node
    printPositiveTestHeader(stdout, "psMetadata", "Test B - Add leaf node on top of existing leaf node");
    if(!psMetadataAddItem(metadata, item1a, PS_LIST_HEAD)) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem returned false for adding a node top.");
        return 20;
    }
    if (!psMetadataAddItem(metadata, item1b, PS_LIST_HEAD)) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem returned false for adding a node top.");
        return 21;
    }

    printFooter(stdout, "psMetadata", "Test B - Add leaf node on top of existing leaf node", true);


    // Test C - Add leaf node to existing folder node
    printPositiveTestHeader(stdout, "psMetadata", "Test C - Add leaf node to existing folder node");
    if (!psMetadataAddItem(metadata, item1c, PS_LIST_HEAD)) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem return false for adding a not to existing node.");
        return 22;
    }
    printFooter(stdout, "psMetadata", "Test C - Add leaf node to existing folder node", true);


    // Test D - Add folder node on top of existing leaf node
    printPositiveTestHeader(stdout, "psMetadata", "Test D - Add folder node on top of existing leaf node");
    if (!psMetadataAddItem(metadata, item2a, PS_LIST_HEAD)) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem returned false for adding a node to existing leaf node.");
        return 23;
    }
    if (!psMetadataAddItem(metadata, item2b, PS_LIST_HEAD)) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem returned false for adding a nod to existing leaf node.");
        return 24;
    }
    printFooter(stdout, "psMetadata", "Test D - Add folder node on top of existing leaf node", true);


    // Test E - Free psMetadata
    printPositiveTestHeader(stdout, "psMetadata", "Test E - Free psMetadata");
    psFree(item1a);
    psFree(item1b);
    psFree(item1c);
    psFree(item2a);
    psFree(item2b);
    psFree(metadata);
    if ( psMemCheckLeaks(0, NULL, stdout, false) != 0 ) {
        psError(PS_ERR_UNKNOWN, true,"Memory leaks detected.");
        return 25;
    }
    psMemCheckCorruption(0);
    psS32 nBad = psMemCheckCorruption(0);
    if(nBad) {
        printf("ERROR: Found %d bad memory blocks\n", nBad);
    }
    printFooter(stdout, "psMetadata", "Test E - Free psMetadata", true);


    return 0;
}
