/** @file  tst_psVectorSort_02.c
 *
 *  @brief Test driver for psVectorSort functions
 *
 *  This test driver contains the following tests for psVectorSort test point 2:
 *     A)  Create vectors
 *     B)  Sort integer vector of indices based on pre-sort order of floating point vector
 *     C)  Attempt to sort with null input vector
 *     D)  Sort with output vector which needs to be resized
 *     E)  Sort input vector with zero elements
 *     F)  Attempt to sort input vector with invalid type
 *     G)  Free vectors
 *
 *  @author  Ross Harman, MHPCC
 *
 *  @version $Revision: 1.7 $  $Name: not supported by cvs2svn $
 *  @date  $Date: 2005-02-17 19:26:24 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
 *
 */

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

#define tstVectorSortIndexByType(datatype,value) \
in = psVectorAlloc( 5, PS_TYPE_##datatype ); \
in->n = 5; \
in->data.datatype[0] = 7+value; \
in->data.datatype[1] = 9+value; \
in->data.datatype[2] = 5+value; \
in->data.datatype[3] = 1+value; \
in->data.datatype[4] = 5+value; \
out = psVectorSortIndex(out,in); \
if(out->type.type != PS_TYPE_U32) { \
    psError(PS_ERR_UNKNOWN,true,"Output vector is not of type PS_TYPE_U32"); \
    return 10; \
} \
if(out->data.U32[0] != 3 ) { \
    psError(PS_ERR_UNKNOWN,true,"Improper index sort out[0] = %ld",out->data.U32[0]); \
    return 20; \
} \
if(out->data.U32[1] != 2 ) { \
    psError(PS_ERR_UNKNOWN,true,"Improper index sort out[1] = %ld",out->data.U32[1]); \
    return 30; \
} \
if(out->data.U32[2] != 4 ) { \
    psError(PS_ERR_UNKNOWN,true,"Improper index sort out[2] = %ld",out->data.U32[2]); \
    return 40; \
} \
if(out->data.U32[3] != 0 ) { \
    psError(PS_ERR_UNKNOWN,true,"Improper index sort out[3] = %ld",out->data.U32[3]); \
    return 50; \
} \
if(out->data.U32[4] != 1 ) { \
    psError(PS_ERR_UNKNOWN,true,"Improper index sort out[4] = %ld",out->data.U32[4]); \
    return 60; \
} \
psFree(in);

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

    // Test A - Sort vectors by index for all types
    printPositiveTestHeader(stdout,"psVectorSortIndex","Sort by index for all types");
    tstVectorSortIndexByType(S8,0)
    tstVectorSortIndexByType(U8,1)
    tstVectorSortIndexByType(S16,2)
    tstVectorSortIndexByType(U16,3)
    tstVectorSortIndexByType(S32,4)
    tstVectorSortIndexByType(U32,5)
    tstVectorSortIndexByType(S64,6)
    tstVectorSortIndexByType(U64,7)
    tstVectorSortIndexByType(F32,8)
    tstVectorSortIndexByType(F64,9)
    psFree(out);
    printFooter(stdout,"psVectorSortIndex","Sort by index for all types",true);

    // Test  C  Attempt to sort with null input vector
    printPositiveTestHeader(stdout,"psVectorSortIndex","Attempt to sort with NULL input");
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
    in = NULL;
    out = psVectorAlloc(5,PS_TYPE_U32);
    out = psVectorSortIndex(out,in);
    if(out != NULL) {
        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with NULL input specified");
        return 111;
    }
    printFooter(stdout,"psVectorSortIndex","Attempt to sort with NULL input",true);

    // Test  D  Sort with output vector which needs to be resized
    printPositiveTestHeader(stdout,"psVectorSortIndex","Sort with resize output vector");
    in = psVectorAlloc(5,PS_TYPE_U8);
    for(psS32 m=0; m<5; m++) {
        in->data.U8[m]= 20-m;
    }
    out = psVectorAlloc(3,PS_TYPE_U32);
    out = psVectorSortIndex(out,in);
    if(out->n != 5) {
        psError(PS_ERR_UNKNOWN,true,"Did not properly resize output vector");
        return 112;
    }
    if(out->data.U32[0] != 4) {
        psError(PS_ERR_UNKNOWN,true,"Did not properly sort index out[0] = %d",out->data.U32[0]);
        return 113;
    }
    if(out->data.U32[1] != 3) {
        psError(PS_ERR_UNKNOWN,true,"Did not properly sort index out[1] = %d",out->data.U32[1]);
        return 114;
    }
    if(out->data.U32[2] != 2) {
        psError(PS_ERR_UNKNOWN,true,"Did not properly sort index out[2] = %d",out->data.U32[2]);
        return 115;
    }
    if(out->data.U32[3] != 1) {
        psError(PS_ERR_UNKNOWN,true,"Did not properly sort index out[3] = %d",out->data.U32[3]);
        return 116;
    }
    if(out->data.U32[4] != 0) {
        psError(PS_ERR_UNKNOWN,true,"Did not properly sort index out[4] = %d",out->data.U32[4]);
        return 117;
    }
    psFree(in);
    psFree(out);
    printFooter(stdout,"psVectorSortIndex","Sort with resize output vector",true);

    // Test E - Sort input vector with zero elements
    printPositiveTestHeader(stdout,"psVectorSortIndex","Sort with input vector with zero elements");
    in = psVectorAlloc(5,PS_TYPE_U8);
    out = psVectorAlloc(5,PS_TYPE_U32);
    in->n = 0;
    out->n = 0;
    tempVect = out;
    out = psVectorSortIndex(out,in);
    if ( out != tempVect ) {
        psError(PS_ERR_UNKNOWN,true,"Did not return the same output vector");
        return 118;
    }
    in->n=5;
    out->n=5;
    psFree(out);
    psFree(in);
    printFooter(stdout,"psVectorSortIndex","Sort with input vector with zero elements",true);

    // Test F - Attempt to sort input vector with invalid type
    printPositiveTestHeader(stdout,"psVectorSortIndex","Attempt to sort with invalid type");
    in = psVectorAlloc(5,PS_TYPE_U8);
    out = psVectorAlloc(5,PS_TYPE_U32);
    tempVect = out;
    in->type.type = PS_TYPE_BOOL;
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate two error messages(psVectorSort,psVectorSortIndex)");
    out = psVectorSortIndex(out,in);
    if( out != tempVect) {
        psError(PS_ERR_UNKNOWN,true,"Did not return the same output vector");
        return 119;
    }
    in->type.type = PS_TYPE_U8;
    psFree(in);
    psFree(out);
    printFooter(stdout,"psVectorSortIndex","Attempt to sort with invalid type",true);

    // Test G - Free vectors
    printPositiveTestHeader(stdout,"psVectorSortIndex", "Free vectors");
    psS32 nLeaks = psMemCheckLeaks(0, NULL, stdout, false);
    if(nLeaks) {
        printf("ERROR: Found %d memory leaks\n", nLeaks);
        return 222;
    }
    psS32 nBad = psMemCheckCorruption(0);
    if(nBad) {
        printf("ERROR: Found %d bad memory blocks\n", nBad);
        return 333;
    }
    printFooter(stdout, "psVectorSort", "Free vectors", true);

}
