/** @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.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 tstVectorSortIndexByType(datatype,value) \
diag( "tstVectorSortIndexByType_" #datatype ); \
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); \
ok(out->type.type == PS_TYPE_S32, \
   "Output vector is of type PS_TYPE_S32"); \
ok(out->data.U32[0] == 3,  \
   "index sort out[0] = %ld",out->data.U32[0]); \
ok(out->data.U32[1] == 2, \
   "index sort out[1] = %ld",out->data.U32[1]); \
ok(out->data.U32[2] == 4, \
   "index sort out[2] = %ld",out->data.U32[2]); \
ok(out->data.U32[3] == 0, \
   "index sort out[3] = %ld",out->data.U32[3]); \
ok(out->data.U32[4] == 1, \
   "index sort out[4] = %ld",out->data.U32[4]); \
psFree(in);


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

    psVector *in = NULL;
    psVector *out = NULL;
    psVector *tempVect = NULL;

    // Test A - Sort vectors 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);

    // Test  C  Attempt to sort with null input vector
    in = NULL;
    out = psVectorAlloc(5,PS_TYPE_U32);
    out = psVectorSortIndex(out,in);
    ok(out == NULL, "Did return NULL with NULL input specified");

    // Test  D  Sort with output vector which needs to be resized
    in = psVectorAlloc(5,PS_TYPE_U8);
    in->n=5;
    for(psS32 m=0; m<5; m++) {
        in->data.U8[m]= 20-m;
    }
    out = psVectorAlloc(5,PS_TYPE_U32);
    out->n = 5;
    out = psVectorSortIndex(out,in);
    ok(out->n == 5, "Did properly resize output vector...out->n=%d, in->n=%d", out->n, in->n);
    ok(out->data.U32[0] == 4,
       "Did properly sort index out[0] = %d",out->data.U32[0]);
    ok(out->data.U32[1] == 3,
       "Did properly sort index out[1] = %d",out->data.U32[1]);
    ok(out->data.U32[2] == 2,
       "Did properly sort index out[2] = %d",out->data.U32[2]);
    ok(out->data.U32[3] == 1,
       "Did properly sort index out[3] = %d",out->data.U32[3]);
    ok(out->data.U32[4] == 0,
       "Did properly sort index out[4] = %d",out->data.U32[4]);

    psFree(in);
    psFree(out);

    // Test E - Sort 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);
    ok ( out == tempVect, "Did not return the same output vector");
    in->n=5;
    out->n=5;
    psFree(out);
    psFree(in);

    // Test F - Attempt to sort input vector with invalid type
    in = psVectorAlloc(5,PS_TYPE_U8);
    out = psVectorAlloc(5,PS_TYPE_U32);
    in->n = 5;
    out->n = 5;
    tempVect = out;
    in->type.type = PS_TYPE_BOOL;
    out = psVectorSortIndex(out,in);
    ok( out == NULL, "Did return NULL");
    in->type.type = PS_TYPE_U8;
    psFree(in);

    // Test G - Free vectors
    psS32 nLeaks = psMemCheckLeaks(0, NULL, stdout, false);
    ok(!nLeaks, "Found %d memory leaks\n", nLeaks);
    psS32 nBad = psMemCheckCorruption(stderr, false);
    ok(!nBad, "Found %d bad memory blocks\n", nBad);
}
