/** @file  tst_psVectorSort_01.c
 *
 *  @brief Test driver for psVectorSort functions
 *
 *  This test driver contains the following tests for psVectorSort test point 1:
 *     A)  Sort input vector to output vector for all types
 *     B)  Sort input float vector into itself
 *     C)  Attempt to sort vector with invalid type (i.e. PS_TYPE_BOOL)
 *     D)  Sort input vector with zero items 
 *     C)  Free float vectors
 *
 *  @author  Ross Harman, MHPCC
 *
 *  @version $Revision: 1.7 $  $Name: not supported by cvs2svn $
 *  @date  $Date: 2005-03-17 19:26:19 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
 *
 */

#include "pslib.h"
#include "psTest.h"

#define tstVectorSortByType(datatype,value)   \
in = psVectorAlloc(7,PS_TYPE_##datatype); \
in->n = 7;  \
out = psVectorAlloc(7,PS_TYPE_##datatype); \
out->n = 7;  \
in->data.datatype[0] = 7+value; \
in->data.datatype[1] = 9+value; \
in->data.datatype[2] = 3+value; \
in->data.datatype[3] = 1+value; \
in->data.datatype[4] = 5+value; \
in->data.datatype[5] = 5+value; \
in->data.datatype[6] = 0+value; \
tempVec = out; \
out = psVectorSort(out, in); \
if(tempVec != out) {  \
    psError(PS_ERR_UNKNOWN,true,"Return value not equal to orignal output argument passed to function"); \
    return 5; \
} \
if(out->data.datatype[0] != in->data.datatype[6]) { \
    psError(PS_ERR_UNKNOWN,true,"Improper sort out[0] type %s",#datatype); \
    return 10; \
} \
if(out->data.datatype[1] != in->data.datatype[3]) { \
    psError(PS_ERR_UNKNOWN,true,"Improper sort out[1] type %s",#datatype); \
    return 20; \
} \
if(out->data.datatype[2] != in->data.datatype[2]) { \
    psError(PS_ERR_UNKNOWN,true,"Improper sort out[2] type %s",#datatype); \
    return 30; \
} \
if(out->data.datatype[3] != in->data.datatype[4]) { \
    psError(PS_ERR_UNKNOWN,true,"Improper sort out[3] type %s",#datatype); \
    return 40; \
} \
if(out->data.datatype[4] != in->data.datatype[5]) { \
    psError(PS_ERR_UNKNOWN,true,"Improper sort out[4] %s",#datatype); \
    return 50; \
} \
if(out->data.datatype[5] != in->data.datatype[0]) { \
    psError(PS_ERR_UNKNOWN,true,"Improper sort out[5] %s",#datatype); \
    return 60; \
} \
if(out->data.datatype[6] != in->data.datatype[1]) { \
    psError(PS_ERR_UNKNOWN,true,"Improper sort out[6] %s",#datatype); \
    return 70; \
} \
psFree(in); \
psFree(out);



psS32 main(psS32 argc,
           char* argv[])
{
    psVector *in = NULL;
    psVector *out = NULL;
    psVector *tempVec = NULL;

    // Test A - Verify the sort for all supported types
    printPositiveTestHeader(stdout,"psVectorSort","Sort all types");
    tstVectorSortByType(S8,0);
    tstVectorSortByType(S16,1);
    tstVectorSortByType(S32,2);
    tstVectorSortByType(S64,3);
    tstVectorSortByType(U8,4);
    tstVectorSortByType(U16,5);
    tstVectorSortByType(U32,6);
    tstVectorSortByType(U64,7);
    tstVectorSortByType(F32,8);
    tstVectorSortByType(F64,9);
    printFooter(stdout,"psVectorSort","Sort all types",true);

    // Test B - Sort input vector into itself
    printPositiveTestHeader(stdout,"psVectorSort", "Sort input float vector into itself");
    in = psVectorAlloc(7, PS_TYPE_F32);
    in->n = 7;
    in->data.F32[0] = 0.7f;
    in->data.F32[1] = 0.9f;
    in->data.F32[2] = 0.3f;
    in->data.F32[3] = 0.1f;
    in->data.F32[4] = 0.5f;
    in->data.F32[5] = 0.5f;
    in->data.F32[6] = -2.0f;
    in = psVectorSort(in, in);
    if(in->data.F32[0] != -2.0f) {
        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[0]");
        return 100;
    }
    if(in->data.F32[1] != 0.1f) {
        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[1]");
        return 200;
    }
    if(in->data.F32[2] != 0.3f) {
        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[2]");
        return 300;
    }
    if(in->data.F32[3] != 0.5f) {
        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[3]");
        return 400;
    }
    if(in->data.F32[4] != 0.5f) {
        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[4]");
        return 500;
    }
    if(in->data.F32[5] != 0.7f) {
        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[5]");
        return 600;
    }
    if(in->data.F32[6] != 0.9f) {
        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[6]");
        return 700;
    }
    printFooter(stdout, "psVectorSort", "Sort input float vector into itself", true);

    // Test C - Attempt to sort vector with invalid type
    printPositiveTestHeader(stdout,"psVectorSort","Invalid vector type");
    in->type.type = PS_TYPE_BOOL;
    out = psVectorAlloc(7,PS_TYPE_F32);
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error messgae");
    tempVec = psVectorSort(out,in);
    if(tempVec != out) {
        psError(PS_ERR_UNKNOWN,true,"Did not return the specified output vector");
        return 33;
    }
    psFree(out);
    printFooter(stdout,"psVectorSort","Invalid vector type",true);

    // Test D - Sort vector with zero elements
    printPositiveTestHeader(stdout,"psVectorSort","Sort zero element vector");
    out = psVectorAlloc(7,PS_TYPE_F32);
    tempVec = out;
    in->n = 0;
    out = psVectorSort(out,in);
    if(tempVec != out) {
        psError(PS_ERR_UNKNOWN,true,"Did not return the specified output vector");
        return 44;
    }
    if(out->n != 0) {
        psError(PS_ERR_UNKNOWN,true,"Did not proper set the number of elements to zero");
        return 55;
    }
    printFooter(stdout,"psVectorSort","Sort zero element vector",true);


    // Test D - Free float vectors
    printPositiveTestHeader(stdout,"psVectorSort", "Free float vectors");
    psFree(in);
    psFree(out);
    if ( psMemCheckLeaks(0, NULL, stdout, false)) {
        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
        return 10;
    }
    psS32 nBad = psMemCheckCorruption(0);
    if(nBad) {
        printf("ERROR: Found %d bad memory blocks\n", nBad);
    }
    printFooter(stdout, "psVectorSort", "Free float vectors", true);

    return 0;
}
