/**
 *  C Implementation: tap_psMetadataConfig_input
 *
 * Description:  Tests for psMetadataConfigRead & psMetadataConfigParse
 *
 * Author: dRob <David.Robbins@mhpcc.hpc.mil>, (C) 2006
 *
 * Copyright: See COPYING file that comes with this distribution
 *
 */

#include <pslib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>


#include "tap.h"
#include "pstap.h"

static void testMetaConfigRead(void);
static void testMetaConfigParse(void);


int main(void)
{
    plan_tests(33);

    note("Tests for psMetadataConfig Input Functions");

    testMetaConfigRead();
    testMetaConfigParse();

    done();
}

void testMetaConfigRead(void)
{
    note("  >>>Test 1:  psMetadataConfigRead");

    //Return NULL for NULL filename input
    {
        unsigned int nfail = 0;
        psMetadata *out = psMetadataConfigRead(NULL, &nfail, NULL, false);
        ok( out == NULL,
            "psMetadataConfigRead:           return NULL for NULL filename input.");
    }
    //Return NULL for invalid filename input
    {
        unsigned int nfail = 0;
        psMetadata *out = psMetadataConfigRead(NULL, &nfail, ".", false);
        ok( out == NULL,
            "psMetadataConfigRead:           return NULL for invalid filename input.");
    }
    //Return NULL for missing file input
    {
        unsigned int nfail = 0;
        psMetadata *out = psMetadataConfigRead(NULL, &nfail, "table4.dat", false);
        ok( out == NULL,
            "psMetadataConfigRead:           return NULL for missing file input.");
    }
    //Return empty metadata for read-only file with invalid syntax
    {
        unsigned int nfail = 0;
        psMetadata *out = psMetadataConfigRead(NULL, &nfail, "table3.dat", false);
        ok( out != NULL && out->list->n == 0,
            "psMetadataConfigRead:           return empty metadata for file"
            " with invalid syntax.");
        psFree(out);
    }
    //Return true for valid inputs - overwrite = false
    {
        unsigned int nfail = 0;
        psMetadata *out = psMetadataConfigRead(NULL, &nfail, "metaconf.in", false);
        psMetadataItem *tempItem = psMetadataGet(out, PS_LIST_HEAD);
        ok( out != NULL && nfail == 25,
            "psMetadataConfigRead:           return correct metadata for valid inputs.");
        skip_start(  tempItem == NULL, 6,
                     "Skipping 1 tests because metadata container is empty!");
        ok_str( tempItem->name, "item1",
                "psMetadataConfigRead:           return correct metadataItem name from "
                "returned metadata.");
        ok( tempItem->type == PS_DATA_BOOL && tempItem->data.B == true,
            "psMetadataConfigRead:           return correct metadataItem data from "
            "returned metadata.");
        ok_str( tempItem->comment, "I am a boolean",
                "psMetadataConfigRead:           return correct metadataItem comment from "
                "returned metadata.");
        tempItem = psMetadataGet(out, PS_LIST_TAIL);
        ok_str( tempItem->name, "meta1",
                "psMetadataConfigRead:           return correct metadataItem name from "
                "returned metadata.");
        ok( tempItem->type == PS_DATA_METADATA &&
            ((psMetadata*)(tempItem->data.V))->list->n == 1
            && strlen(tempItem->comment) == 0,
            "psMetadataConfigRead:          return correct metadataItem data from "
            "returned metadata.");
        skip_end();
        // psMetadataConfigWrite(out, "mdc-overwrite_false.txt");
        psFree(out);
    }
    //Return true for valid inputs - overwrite = true
    {
        unsigned int nfail = 0;
        psMetadata *out = psMetadataConfigRead(NULL, &nfail, "metaconf.in", true);
        psMetadataItem *tempItem = psMetadataGet(out, PS_LIST_HEAD);
        ok( out != NULL  && nfail == 21,
            "psMetadataConfigRead:          return correct metadata for valid inputs.");
        skip_start(  tempItem == NULL, 6,
                     "Skipping 1 tests because metadata container is empty!");
        ok_str( tempItem->name, "item1",
                "psMetadataConfigRead:          return correct metadataItem name from "
                "returned metadata.");
        ok( tempItem->type == PS_DATA_BOOL && tempItem->data.B == false,
            "psMetadataConfigRead:          return correct metadataItem data from "
            "returned metadata.");
        ok_str( tempItem->comment, "I am a boolean2",
                "psMetadataConfigRead:          return correct metadataItem comment from "
                "returned metadata.");
        tempItem = psMetadataGet(out, PS_LIST_TAIL);
        ok_str( tempItem->name, "DD2",
                "psMetadataConfigRead:          return correct metadataItem name from "
                "returned metadata.");
        ok( tempItem->type == PS_DATA_METADATA &&
            ((psMetadata*)(tempItem->data.V))->list->n == 1
            && strlen(tempItem->comment) == 0,
            "psMetadataConfigRead:          return correct metadataItem data from "
            "returned metadata.");
        skip_end();
        // psMetadataConfigWrite(out, "mdc-overwrite_true.txt");
        psFree(out);
    }

    //Check for Memory leaks
    checkMem();
}

void testMetaConfigParse(void)
{
    note("  >>>Test 2:  psMetadataConfigParse");
    char str1[70];
    char str2[70];
    char str3[70];
    char str4[70];
    char str5[70];
    char str6[70];
    char str7[70];
    char str8[70];
    char str9[70];
    strcpy(str1, "-10.05    2        4");
    strcpy(str2, "new S32       666");
    strcpy(str3, "item4            F64       6.28");
    strcpy(str4, "item8            S8        3\nitem8            S8        5");
    strcpy(str5, "item1            BOOL      T");
    strcpy(str6, "item6            S16");
    strcpy(str7, "@vector6 U8 1 2 3 4 5   # I am a vector");
    strcpy(str8, "time01           TAI       1970-01-01T00:16:39Z  # I am time");
    strcpy(str9, "END\n");

    //Return NULL for NULL string input
    {
        unsigned int nfail = 0;
        psMetadata *out = psMetadataConfigParse(NULL, &nfail, NULL, false);
        ok( out == NULL,
            "psMetadataConfigParse:         return NULL for NULL string input.");
    }
    //Return empty metadata for incorrect string input
    {
        psMetadata *out = psMetadataConfigParse(NULL, NULL, str1, false);
        psMetadataItem *tempItem = psMetadataGet(out, PS_LIST_HEAD);
        ok( out != NULL && tempItem == NULL,
            "psMetadataConfigParse:         return empty metadata for invalid "
            "string input.");
        psFree(out);
    }
    //Return correct metadata for correct string input - S32
    {
        psMetadata *out = psMetadataConfigParse(NULL, NULL, str2, false);
        psMetadataItem *tempItem = psMetadataGet(out, PS_LIST_HEAD);
        ok( out != NULL && tempItem != NULL,
            "psMetadataConfigParse:         return correct metadata for valid "
            "string input. (S32)");
        skip_start(  tempItem == NULL, 2,
                     "Skipping 1 tests because metadata container is empty!");
        ok( tempItem->type == PS_TYPE_S32 && tempItem->data.S32 == 666,
            "psMetadataConfigParse:         return correct metadataItem data (S32)");
        ok_str( tempItem->name, "new",
                "psMetadataConfigParse:         return correct metadataItem name (S32)");
        skip_end();
        psFree(out);
    }
    //Return correct metadata for correct string input - F64
    {
        psMetadata *out = psMetadataConfigParse(NULL, NULL, str3, false);
        psMetadataItem *tempItem = psMetadataGet(out, PS_LIST_HEAD);
        ok( out != NULL && tempItem != NULL,
            "psMetadataConfigParse:         return correct metadata for valid "
            "string input. (F64)");
        skip_start(  tempItem == NULL, 2,
                     "Skipping 1 tests because metadata container is empty!");
        ok( tempItem->type == PS_DATA_F64,
            "psMetadataConfigParse:         return correct metadataItem data (F64) "
            "from outputted metadata.");
        ok_float(6.28, tempItem->data.F64,
                 "psMetadataConfigParse:         return correct metadataItem data (F64) "
                 "value.");
        ok_str( tempItem->name, "item4",
                "psMetadataConfigParse:         return correct metadataItem name (F64)");
        skip_end();
        psFree(out);
    }
    //Return correct metadata for string with duplicate entry - S8
    {
        unsigned int nfail = 0;
        psMetadata *out = psMetadataConfigParse(NULL, &nfail, str4, false);
        psMetadataItem *tempItem = psMetadataGet(out, PS_LIST_HEAD);
        ok( out != NULL && tempItem != NULL && out->list->n == 1  && nfail == 1,
            "psMetadataConfigParse:         return correct metadata for string "
            "with duplicate entry. (S8)");
        skip_start(  tempItem == NULL, 2,
                     "Skipping 1 tests because metadata container is empty!");
        ok( tempItem->type == PS_TYPE_S8 && tempItem->data.S8 == 3,
            "psMetadataConfigParse:         return correct metadataItem data (S8)");
        ok_str( tempItem->name, "item8",
                "psMetadataConfigParse:         return correct metadataItem name (S8)");
        skip_end();
        psFree(out);
    }
    //Return correct metadata for correct string input - Vector
    {
        psMetadata *out = psMetadataConfigParse(NULL, NULL, str7, true);
        psMetadataItem *tempItem = psMetadataGet(out, PS_LIST_HEAD);
        ok( out != NULL && tempItem != NULL,
            "psMetadataConfigParse:         return correct metadata for valid "
            "string input. (Vector)");
        skip_start(  tempItem == NULL, 2,
                     "Skipping 1 tests because metadata container is empty!");
        ok( tempItem->type == PS_DATA_VECTOR
            && ((psVector*)(tempItem->data.V))->data.U8[0] == 1,
            "psMetadataConfigParse:         return correct metadataItem data (Vector) ");
        ok_str( tempItem->name, "vector6",
                "psMetadataConfigParse:         return correct metadataItem name (Vector)");
        skip_end();
        psFree(out);
    }
    //Return empty metadata for incorrect string input
    {
        psMetadata *out = psMetadataConfigParse(NULL, NULL, str9, false);
        psMetadataItem *tempItem = psMetadataGet(out, PS_LIST_HEAD);
        ok( out != NULL && tempItem == NULL,
            "psMetadataConfigParse:         return empty metadata for invalid "
            "string input.");
        psFree(out);
    }
    // Check for Memory leaks
    checkMem();

}

