/** @file  tst_psArray.c
 *
 *  @brief Test driver for psArray integer functions
 *
 *  This test driver contains the following tests for psArray test point 1:
 *     A)  Create void pointer array
 *     B)  Add data to void pointer array
 *     C)  Sort data in array
 *     D)  Attempt to sort data in invalid array
 *     E)  Free void pointer array
 *
 *  @author  Ross Harman, MHPCC
 *
 *  @version $Revision: 1.3 $  $Name: not supported by cvs2svn $
 *  @date  $Date: 2004-11-30 01:26:47 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
 *
 */

#include <math.h>

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

typedef struct
{
    psS32 x;
    float y;
}
testStruct;

int testStructCompare(const void **a, const void **b)
{
    testStruct* first = (testStruct*)*a;
    testStruct* second = (testStruct*)*b;

    if(first->x < second->x)
        return -1;
    else if (first->x > second->x)
        return 1;
    else
        return 0;
}

psS32 main(psS32 argc,
           char* argv[])
{
    // Create array of pointers
    testStruct *mySt[10];

    // Test A - Create void pointer array
    printPositiveTestHeader(stdout,"psArray", "Create void pointer array");
    psArray *psArr = psArrayAlloc(10);
    if (psArr->nalloc != 10) {
        psError(PS_ERR_UNKNOWN, true,"psArray didn't have proper number of elements.");
        return 1;
    }
    printFooter(stdout, "psArray", "Create void pointer array", true);

    // Test B - Add data to void pointer array
    printPositiveTestHeader(stdout, "psArray", "Add data to void pointer array");
    for(psS32 i = 0; i < 10; i++) {
        testStruct *ts = psAlloc(sizeof(testStruct));
        ts->x = 10*(10-i);
        ts->y = 10.1*(10-i);
        mySt[i] = ts;
        psArr->data[i] = ts;
        psMemIncrRefCounter(ts);
    }

    for(psS32 i = 0; i < 10; i++) {
        testStruct *ts = (testStruct*)psArr->data[i];
        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
        if (fabsf(ts->x - 10*(10-i)) > 0.01f || fabsf(ts->y - 10.1*(10-i)) > 0.01f) {
            psError(PS_ERR_UNKNOWN, true,"Couldn't properly get elements from array.");
            return 2;
        }
    }
    printf("array size = %d\n", psArr->nalloc);
    if (psArr->nalloc != 10) {
        psError(PS_ERR_UNKNOWN, true,"Array Size wrong");
        return 3;
    }
    printf("array population = %d\n", psArr->n);
    if (psArr->n != 10) {
        psError(PS_ERR_UNKNOWN, true,"Array population wrong");
        return 4;
    }
    printFooter(stdout, "psArray", "Add data to void pointer array", true);

    // Test C - Sort data in array
    printPositiveTestHeader(stdout,"psArray","Sort data in array");
    psArr = psArraySort(psArr,testStructCompare);
    for(psS32 i = 0; i < 10; i++) {
        testStruct *ts = (testStruct*)psArr->data[i];
        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
        if (fabsf(ts->x - 10*(i+1)) > 0.01f || fabsf(ts->y - 10.1*(i+1)) > 0.01f) {
            psError(PS_ERR_UNKNOWN, true,"Couldn't properly get elements from array.");
            return 5;
        }
    }
    printFooter(stdout,"psArray","Sort data in array",true);

    // Test D - Attempt to sort null array
    printPositiveTestHeader(stdout,"psArray","Attempt to sort array");
    psArray* tempArr = psArraySort(NULL,testStructCompare);
    if(tempArr != NULL) {
        psError(PS_ERR_UNKNOWN,true,"Array sort did not return null when sorting null array");
        return 6;
    }
    printFooter(stdout,"psArray","Attempt to sort array",true);

    // Test E - Free void pointer array
    printPositiveTestHeader(stdout, "psArray", "Free void pointer array");
    psFree(psArr);
    for(psS32 i = 0; i < 10; i++) {
        psFree(mySt[i]);
    }
    if( psMemCheckLeaks(0, NULL, stdout, false) != 0) {
        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
        return 110;
    }
    psS32 nBad = psMemCheckCorruption(0);
    if(nBad) {
        printf("ERROR: Found %d bad memory blocks\n", nBad);
        return 111;
    }
    printFooter(stdout, "psArray" ,"Free void pointer array", true);

    return 0;
}
