/** @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.2 $  $Name: not supported by cvs2svn $
 *  @date  $Date: 2007-01-24 22:14:48 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
 *
 */

#include <pslib.h>

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


#define tstVectorSortByType(datatype,value)   \
diag( "tstVectorSortByType_" #datatype ); \
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); \
ok(tempVec == out, \
   "Return value equal to orignal output argument passed to function"); \
skip_start(tempVec != out, \
           7,"Return value not equal to orignal output argument passed to function"); \
ok(out->data.datatype[0] == in->data.datatype[6], \
   "sort out[0] type %s",#datatype); \
skip_start(out->data.datatype[0] != in->data.datatype[6], \
           6,"sort out[0] type %s",#datatype); \
ok(out->data.datatype[1] == in->data.datatype[3], \
   "sort out[1] type %s",#datatype); \
skip_start(out->data.datatype[1] != in->data.datatype[3], \
           5,"Improper sort out[1] type %s",#datatype); \
ok(out->data.datatype[2] == in->data.datatype[2], \
   "sort out[2] type %s",#datatype); \
skip_start(out->data.datatype[2] != in->data.datatype[2], \
           4,"Improper sort out[2] type %s",#datatype); \
ok(out->data.datatype[3] == in->data.datatype[4], \
   "sort out[3] type %s",#datatype); \
skip_start(out->data.datatype[3] != in->data.datatype[4], \
           3,"Improper sort out[3] type %s",#datatype); \
ok(out->data.datatype[4] == in->data.datatype[5], \
   "sort out[4] %s",#datatype); \
skip_start(out->data.datatype[4] != in->data.datatype[5], \
           2,"Improper sort out[4] %s",#datatype); \
ok(out->data.datatype[5] == in->data.datatype[0], \
   "sort out[5] %s",#datatype); \
skip_start(out->data.datatype[5] != in->data.datatype[0], \
           1,"Improper sort out[5] %s",#datatype); \
ok(out->data.datatype[6] == in->data.datatype[1], \
   "sort out[6] %s",#datatype); \
skip_end(); \
skip_end(); \
skip_end(); \
skip_end(); \
skip_end(); \
skip_end(); \
skip_end(); \
psFree(in); \
psFree(out);



psS32 main(psS32 argc,
           char* argv[])
{
    plan_tests(92);

    psVector *in = NULL;
    psVector *out = NULL;
    psVector *tempVec = NULL;

    // Test A - Verify the sort for all supported 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);


    // Test B - Sort input 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);
    ok(in->data.F32[0] == -2.0f,"self sort in[0]");
    ok(in->data.F32[1] == 0.1f,"self sort in[1]");
    ok(in->data.F32[2] == 0.3f, "self sort in[2]");
    ok(in->data.F32[3] == 0.5f, "self sort in[3]");
    ok(in->data.F32[4] == 0.5f, "self sort in[4]");
    ok(in->data.F32[5] == 0.7f, "self sort in[5]");
    ok(in->data.F32[6] == 0.9f, "self sort in[6]");

    // Test C - Attempt to sort vector with invalid type
    in->type.type = PS_TYPE_BOOL;
    out = psVectorAlloc(7,PS_TYPE_F32);
    tempVec = psVectorSort(out,in);
    ok(tempVec == NULL, "Did return NULL on error");

    // Test D - Sort vector with zero elements
    out = psVectorAlloc(7,PS_TYPE_F32);
    in->n = 0;
    out = psVectorSort(out,in);
    ok (out != NULL, "psVectorSort returned a non-NULL vector" );
    skip_start (out == NULL, 1, "psVectorSort returned a NULL vector" );
    ok (out->n == 0, "psVectorSort correctly return a 0-length vector.\n");
    skip_end();

    psFree(out);


    // Test D - Free float vectors
    psFree(in);
    ok ( ! psMemCheckLeaks(0, NULL, stdout, false),"Memory leaks not detected");

    psS32 nBad = psMemCheckCorruption(stderr, false);
    ok(!nBad, "Found %d bad memory blocks\n", nBad);
}
