/** @file  tst_psMetadata_02.c
*
*  @brief Test driver for psMetadata functions
*
*  This test driver contains the following tests for psMetadata:
*     Test A - Allocate metadata items
*     Test B - Attempt to create metadata item with null name
*     Test C - Attempt to create metadata item with invalid type
*     Test D - Allocate metadata
*     Test E - Attempt to add metadata item to null metadata
*     Test F - Attempt to add null metadata item to metadata
*     Test G - Free psMetadata
*
*  @author  Ross Harman, MHPCC
*
*  @version $Revision: 1.9 $  $Name: not supported by cvs2svn $
*  @date  $Date: 2004-12-03 23:19:07 $
*
*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
*
*/

#include "pslib.h"
#include "psTest.h"
#include <string.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 *item1 = NULL;
    psMetadata *metadata = NULL;
    psMetadataItem *item2 = NULL;
    psMetadataItem *item3 = NULL;
    psMetadataItem *item4 = NULL;
    psMetadataItem *item5 = NULL;
    psMetadataItem *badItem = NULL;


    // Test A - Allocate metadata items
    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
    item1 = psMetadataItemAlloc("myItem1", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
    item2 = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 111);
    item3 = psMetadataItemAlloc("myItem3", PS_TYPE_F32, PS_META_PRIMITIVE, "I am a single precision floating point", 222.222);
    item4 = psMetadataItemAlloc("myItem4", PS_TYPE_F64, PS_META_PRIMITIVE, "I am a double precision floating point", 333.333);
    item5 = psMetadataItemAlloc("myItem5", PS_TYPE_PTR, PS_META_STR, "I am a string", "HELLO WORLD");
    printMetadataItem(item1);
    printMetadataItem(item2);
    printMetadataItem(item3);
    printMetadataItem(item4);
    printMetadataItem(item5);
    printFooter(stdout, "psMetadata", "Test A - Allocate metadata items", true);


    // Test B - Attempt to create metadata item with null name
    printNegativeTestHeader(stdout,"psMetadata", "Test B - Attempt to create metadata item with null name",
                            "Null value for name not allowed", 0);
    psLogMsg(__func__,PS_LOG_INFO,"Following should produce error for null name.");
    badItem = psMetadataItemAlloc(NULL, PS_TYPE_PTR, PS_META_STR, "I am a string", "HELLO WORLD");
    if (badItem != NULL) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataItemAlloc did not return null with null name item.");
        return 10;
    }
    printFooter(stdout, "psMetadata", "Test B - Attempt to create metadata item with null name", true);


    // Test C - Attempt to create metadata item with invalid type
    printNegativeTestHeader(stdout,"psMetadata", "Test C - Attempt to create metadata item with invalid type",
                            "Invalid psMetadataType: 6", 0);
    badItem = psMetadataItemAlloc("badItem", PS_TYPE_PTR, PS_META_NTYPE, "I am bad", "Bad comment");
    printFooter(stdout, "psMetadata", "Test C - Attempt to create metadata item with invalid type", true);


    // Test D - Allocate metadata
    printPositiveTestHeader(stdout, "psMetadata", "Test D - Allocate metadata");
    metadata = psMetadataAlloc();
    printFooter(stdout, "psMetadata", "Test D - Allocate metadata", true);


    // Test E - Attempt add metadata item to null metadata
    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to add metadata item to null metadata",
                            "Null metadata collection not allowed", 0);
    psMetadataAddItem(NULL, item1, PS_LIST_HEAD);
    printFooter(stdout, "psMetadata", "Test E - Attempt to add metadata item to null metadata", true);


    // Test F - Attempt add null metadata item to metadata
    printNegativeTestHeader(stdout,"psMetadata", "Test F - Attempt to add null metadata item to metadata",
                            "Null metadata item not allowed", 0);
    psMetadataAddItem(metadata, NULL, PS_LIST_HEAD);
    printFooter(stdout, "psMetadata", "Test F - Attempt to add null metadata item to metadata", true);


    // Test G - Free psMetadata
    printPositiveTestHeader(stdout, "psMetadata", "Test G - Free psMetadata");
    psFree(item1);
    psFree(item2);
    psFree(item3);
    psFree(item4);
    psFree(item5);
    psFree(badItem);
    psFree(metadata);
    if(psMemCheckLeaks(0, NULL, stdout,false) ) {
        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
        return 10;
    }
    psMemCheckCorruption(0);
    psS32 nBad = psMemCheckCorruption(0);
    if(nBad) {
        printf("ERROR: Found %d bad memory blocks\n", nBad);
    }
    printFooter(stdout, "psMetadata", "Test G - Free psMetadata", true);

    return 0;
}
