/** @file  tst_psVector.c
 *
 *  @brief Test driver for psVector integer functions
 *
 *  This test driver contains the following tests for psVector test point 1:
 *     A)  Create S32 vector
 *     B)  Add data to S32 vector
 *     C)  Reallocate S32 vector bigger
 *     D)  Reallocate S32 vector smaller
 *     E)  Free S32 vector
 *     F)  Attempt to create a S32 vector with zero size
 *     G)  Attempt to realloc a null S32 vector
 *
 *  @author  Ross Harman, MHPCC
 *
 *  @version $Revision: 1.9 $  $Name: not supported by cvs2svn $
 *  @date  $Date: 2005-06-10 21:46:46 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
 *
 */

#include "psTest.h"
#include "pslib_strict.h"

static psS32 testVectorAlloc(void);
static psS32 testVectorRealloc(void);
static psS32 testVectorExtend(void);

testDescription tests[] = {
                              {testVectorAlloc,-1,"psVectorAlloc",0,false},
                              {testVectorRealloc,-2,"psVectorRealloc",0,false},
                              {testVectorExtend,-3,"psVectorExtend",0,false},
                              {NULL}
                          };

psS32 main(psS32 argc, char* argv[])
{
    psLogSetLevel(PS_LOG_INFO);

    if ( ! runTestSuite(stderr,"psVector",tests,argc,argv) ) {
        return 1;
    }
    return 0;
}

psS32 testVectorAlloc(void)
{
    psVector *psVec = psVectorAlloc(5, PS_TYPE_S32);

    if (psVec == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 1;
    }
    if (psVec->nalloc != 5) {
        fprintf(stderr,"Vector size = %d\n", psVec->nalloc);
        return 1;
    }
    if (psVec->n != psVec->nalloc) {
        fprintf(stderr,"Vector population = %d\n", psVec->n);
        return 2;
    }

    if (psVec->type.type != PS_TYPE_S32) {
        fprintf(stderr,"Vector type = %d\n", psVec->type.type);
        return 3;
    }
    if (psVec->type.dimen != PS_DIMEN_VECTOR) {
        fprintf(stderr,"Vector dimen = %d\n", psVec->type.dimen);
        return 4;
    }

    // Test B - Add data to integer vector
    for(psS32 i = 0; i < 5; i++) {
        psVec->data.S32[i] = i*10;
    }

    psVector* vecZero = psVectorAlloc(0, PS_TYPE_S32);
    if(vecZero == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 5;
    }
    if (vecZero->nalloc != 0) {
        fprintf(stderr,"Vector size = %d\n", vecZero->nalloc);
        return 6;
    }
    if (vecZero->n != vecZero->nalloc) {
        fprintf(stderr,"Vector population = %d\n", vecZero->n);
        return 7;
    }

    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
    psVector* vecBogus = psVectorAlloc(10, 0);
    if (vecBogus != NULL) {
        fprintf(stderr,"Huh!  bogus type generated a psVector?");
        return 20;
    }

    psFree(psVec);
    psFree(vecZero);

    return 0;
}

psS32 testVectorRealloc(void)
{
    // create new psVector
    psVector *psVec = psVectorAlloc(5, PS_TYPE_S32);
    if (psVec == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 30;
    }
    for(psS32 i = 0; i < 5; i++) {
        psVec->data.S32[i] = i*10;
    }

    // Test C - Reallocate S32 vector bigger
    psVec = psVectorRealloc(psVec,10);
    if (psVec == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 1;
    }
    if (psVec->nalloc != 10) {
        fprintf(stderr,"Vector size = %d\n", psVec->nalloc);
        return 1;
    }
    if (psVec->n != 5) {
        fprintf(stderr,"Vector population = %d\n", psVec->n);
        return 2;
    }

    if (psVec->type.type != PS_TYPE_S32) {
        fprintf(stderr,"Vector type = %d\n", psVec->type.type);
        return 3;
    }
    if (psVec->type.dimen != PS_DIMEN_VECTOR) {
        fprintf(stderr,"Vector dimen = %d\n", psVec->type.dimen);
        return 4;
    }

    for(psS32 i = 5; i < 10; i++) {
        psVec->data.S32[i] = i*10;
        psVec->n++;
    }

    for(psS32 i = 0; i < 10; i++) {
        if (psVec->data.S32[i] != i*10) {
            fprintf(stderr,"Elem %d = %d, expected %d\n", i, psVec->data.S32[i], i*10);
            return 5;
        }
    }

    // Test D - Reallocate S32 vector smaller
    psVec = psVectorRealloc(psVec,3);
    if (psVec == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 9;
    }
    if (psVec->nalloc != 3) {
        fprintf(stderr,"Vector size = %d\n", psVec->nalloc);
        return 10;
    }
    if (psVec->n != 3) {
        fprintf(stderr,"Vector population = %d\n", psVec->n);
        return 11;
    }

    for(psS32 i = 0; i < 3; i++) {
        if (psVec->data.S32[i] != i*10) {
            fprintf(stderr,"Elem %d = %d, expected %d\n", i, psVec->data.S32[i], i*10);
            return 12;
        }
    }

    psVec = psVectorRealloc(psVec,0);
    if (psVec == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 20;
    }
    if (psVec->nalloc != 0) {
        fprintf(stderr,"Vector size = %d\n", psVec->nalloc);
        return 21;
    }
    if (psVec->n != 0) {
        fprintf(stderr,"Vector population = %d\n", psVec->n);
        return 22;
    }

    psVector* vecBogus = psVectorRealloc(NULL, 6);
    if (vecBogus != NULL) {
        fprintf(stderr,"Huh!  bogus type generated a psVector?");
        return 25;
    }

    // Test E - Free S32 vector
    psFree(psVec);

    return 0;
}

psS32 testVectorExtend(void)
{
    // create new psVector
    psVector *psVec = psVectorAlloc(5, PS_TYPE_S32);
    if (psVec == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 1;
    }

    psVec->n = 0;

    psVec = psVectorExtend(psVec, 0, 2);
    if (psVec == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 2;
    }
    if (psVec->nalloc != 5) { // no growth should occur
        fprintf(stderr,"Vector size = %d\n", psVec->nalloc);
        return 3;
    }
    if (psVec->n != 2) {
        fprintf(stderr,"Vector population = %d\n", psVec->n);
        return 4;
    }

    psVec = psVectorExtend(psVec, 0, 2);
    if (psVec == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 10;
    }
    if (psVec->nalloc != 15) { // growth should occur
        fprintf(stderr,"Vector size = %d\n", psVec->nalloc);
        return 11;
    }
    if (psVec->n != 4) {
        fprintf(stderr,"Vector population = %d\n", psVec->n);
        return 12;
    }

    psVec = psVectorExtend(psVec, 0, -2);
    if (psVec == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 20;
    }
    if (psVec->nalloc != 15) { // no growth
        fprintf(stderr,"Vector size = %d\n", psVec->nalloc);
        return 21;
    }
    if (psVec->n != 2) {
        fprintf(stderr,"Vector population = %d\n", psVec->n);
        return 22;
    }

    psVec = psVectorExtend(psVec, 0, -20);
    if (psVec == NULL) {
        fprintf(stderr,"ERROR: Return is NULL\n");
        return 30;
    }
    if (psVec->nalloc != 15) { // no growth
        fprintf(stderr,"Vector size = %d\n", psVec->nalloc);
        return 31;
    }
    if (psVec->n != 0) {
        fprintf(stderr,"Vector population = %d\n", psVec->n);
        return 32;
    }

    psFree(psVec);

    return 0;
}
