/** @file  tst_psTime_01.c
 *
 *  @brief Test driver for psTime functions
 *
 *  This test driver contains the following tests for psTime:
 *     A) Get current TAI time
 *     B) Print test time
 *     C) Convert psTime to ISO time
 *     D) Convert ISO time to psTime
 *     E) Convert psTime to UTC time
 *     F) Convert UTC time to psTime
 *     G) Convert psTime to MJD time
 *     H) Convert MJD time to psTime
 *     I) Convert psTime to JD time
 *     J) Convert JD time to psTime
 *     K) Convert psTime to timeval time
 *     L) Convert timeval time to psTime
 *     M) Convert psTime to tm time
 *     N) Convert tm time to psTime
 *     O) Convert psTime time to LMST
 *     P) Free data
 *
 *  @author  Ross Harman, MHPCC
 *
 *  @version $Revision: 1.25 $  $Name: not supported by cvs2svn $
 *  @date  $Date: 2005-04-19 02:13:53 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
 *
 */

#include <string.h>
#include "pslib_strict.h"
#include "psTest.h"

psS32 main(psS32 argc, char* argv[])
{
    psTime *testTime;
    char *testString = "2004-07-21T18:22:24.272Z";

    psLibInit(true,"psTime.config");

    // Test time was taken at July 21, 2004 at 18:22:24.272044
    testTime = (psTime*)psAlloc(sizeof(psTime));
    testTime->sec = 1090434144;
    testTime->nsec = 272044000;
    testTime->type = PS_TIME_TAI;

    // Test A - Get current TAI time
    printPositiveTestHeader(stdout,"psTime", "Get current TAI time");
    psTime *timeA = NULL;
    timeA = psTimeGetNow(PS_TIME_TAI);
    psFree(timeA);
    printFooter(stdout, "psTime", "Get current TAI time", true);


    // Test B - Print test time
    printPositiveTestHeader(stdout,"psTime", "Print test time");
    printf("Test time: Seconds = %lld Nanoseconds = %u\n",
           (long long int)testTime->sec,
           testTime->nsec);
    printFooter(stdout, "psTime", "Print test time", true);


    // Test C - Convert psTime to ISO time
    printPositiveTestHeader(stdout,"psTime", "Convert psTime to ISO time");
    char *isoString;
    isoString = psTimeToISO(testTime);
    printf("%s\n", isoString);
    if(strncmp(isoString, testString, 256)) {
        printf("ERROR - ISO string incorrect\n");
        printf("Returned: %s\n", isoString);
    }
    printFooter(stdout, "psTime", "Convert psTime to ISO time", true);


    // Test D - Convert ISO time to psTime
    printPositiveTestHeader(stdout,"psTime", "Convert ISO time to psTime");
    psTime *timeD = NULL;
    timeD = psTimeFromISO(isoString);
    printf("psTime: Seconds = %lld Nanoseconds = %u\n",
           (long long int)timeD->sec,
           timeD->nsec);
    psFree(isoString);
    psFree(timeD);
    printFooter(stdout, "psTime", "Convert ISO time to psTime", true);


    // Test E - Convert TAI to UTC time
    printPositiveTestHeader(stdout,"psTime", "Convert psTime time to UTC time");
    psTime *timeE = NULL;
    timeE = (psTime*)psAlloc(sizeof(psTime));
    timeE->sec = 1090434144;
    timeE->nsec = 272044000;
    timeE->type = PS_TIME_TAI;
    timeE = psTimeConvert(timeE, PS_TIME_UTC);
    psFree(timeE);
    printf("psTime: Seconds = %lld Nanoseconds = %u\n",
           (long long int)timeE->sec,
           timeE->nsec);
    printFooter(stdout, "psTime", "Convert psTime time to UTC time", true);


    // Test F - Convert UTC time to psTime
    printPositiveTestHeader(stdout,"psTime", "Convert UTC time to psTime");
    psTime *timeF = NULL;
    timeF = (psTime*)psAlloc(sizeof(psTime));
    timeF->sec = 1090434112;
    timeF->nsec = 272044000;
    timeF->type = PS_TIME_UTC;
    timeF = psTimeConvert(timeF, PS_TIME_TAI);
    psFree(timeF);
    printf("psTime: Seconds = %lld Nanoseconds = %u\n",
           (long long int)timeF->sec,
           timeF->nsec);
    printFooter(stdout, "psTime", "Convert UTC time to psTime", true);


    // Test G - Convert psTime to MJD time
    printPositiveTestHeader(stdout,"psTime", "Convert psTime to MJD time");
    double mjdTime = 0.0;
    mjdTime = psTimeToMJD(testTime);
    printf("MJD = %f\n", mjdTime);
    printFooter(stdout, "psTime", "Convert psTime to MJD time", true);


    // Test H - Convert MJD time to psTime
    printPositiveTestHeader(stdout,"psTime", "Convert MJD time to psTime");
    psTime *timeH = NULL;
    timeH = psTimeFromMJD(mjdTime);
    printf("psTime: Seconds = %lld Nanoseconds = %u\n",
           (long long int)timeH->sec,
           timeH->nsec);
    psFree(timeH);
    printFooter(stdout, "psTime", "Convert MJD time to psTime", true);


    // Test I - Convert psTime to JD time
    printPositiveTestHeader(stdout,"psTime", "Convert psTime to JD time");
    double jdTime = 0.0;
    jdTime = psTimeToJD(testTime);
    printf("JD = %f\n", jdTime);
    printFooter(stdout, "psTime", "Convert psTime to JD time", true);


    // Test J - Convert JD time to psTime
    printPositiveTestHeader(stdout,"psTime", "Convert JD time to psTime");
    psTime *timeJ = NULL;
    timeJ = psTimeFromJD(jdTime);
    printf("psTime: Seconds = %lld Nanoseconds = %u\n",
           (long long int)timeJ->sec,
           timeJ->nsec);
    psFree(timeJ);
    printFooter(stdout, "psTime", "Convert JD time to psTime", true);


    // Test K - Convert psTime to timeval time
    printPositiveTestHeader(stdout,"psTime", "Convert psTime to timeval time");
    struct timeval timevalTime;
    timevalTime = psTimeToTimeval(testTime);
    printf("timevalTime: Seconds = %lld Microseconds = %lld\n",
           (long long int)timevalTime.tv_sec,
           (long long int)timevalTime.tv_usec);
    printFooter(stdout, "psTime", "Convert psTime to timeval time", true);


    // Test L - Convert timeval time to psTime
    printPositiveTestHeader(stdout,"psTime", "Convert timeval time to psTime");
    psTime *timeL = NULL;
    timeL = psTimeFromTimeval(&timevalTime);
    printf("psTime: Seconds = %lld Nanoseconds = %u\n",
           (long long int)timeL->sec,
           timeL->nsec);
    psFree(timeL);
    printFooter(stdout, "psTime", "Convert timeval time to psTime", true);


    // Test M - Convert psTime to tm time
    printPositiveTestHeader(stdout,"psTime", "Convert psTime to tm time");
    struct tm *tmTime;
    tmTime = psTimeToTM(testTime);
    printf("tmTime:\n");
    printf("tmTime->tm_year = %d\n", tmTime->tm_year);
    printf("tmTime->tm_mon = %d\n", tmTime->tm_mon);
    printf("tmTime->tm_mday = %d\n", tmTime->tm_mday);
    printf("tmTime->tm_hour = %d\n", tmTime->tm_hour);
    printf("tmTime->tm_min = %d\n", tmTime->tm_min);
    printf("tmTime->tm_sec = %d\n", tmTime->tm_sec);
    printFooter(stdout, "psTime", "Convert psTime to tm time", true);


    // Test N - Convert tm time to psTime
    printPositiveTestHeader(stdout, "psTime", "Convert tm time to psTime");
    psTime *timeN = NULL;
    timeN = psTimeFromTM(tmTime);
    printf("psTime: Seconds = %lld Nanoseconds = %u\n",
           (long long int)timeN->sec,
           timeN->nsec);
    psFree(timeN);
    psFree(tmTime);
    printFooter(stdout, "psTime", "Convert tm time to psTime", true);


    // Test O - psTime to LMST
    printPositiveTestHeader(stdout, "psTime", "Convert psTime time to LST");
    char *testString2 = "2004-09-10T1:00:00.00Z";
    psTime* testTime2 = NULL;
    testTime2 = psTimeFromISO(testString2);
    double dblTime = psTimeToLMST(testTime2, 1);
    printf("LST (rad): %lf\n", dblTime);
    psFree(testTime2);
    printFooter(stdout, "psTime", "Convert psTime time to LST", true);


    // Test P - Free data
    printPositiveTestHeader(stdout, "psMetadata", "Test P - Free data");
    psFree(testTime);
    psLibFinalize();
    if( psMemCheckLeaks(0, NULL, stdout,false) != 0 ) {
        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected");
        return 10;
    }
    psMemCheckCorruption(0);
    psS32 nBad = psMemCheckCorruption(0);
    if(nBad) {
        printf("ERROR: Found %d bad memory blocks\n", nBad);
    }
    printFooter(stdout, "psMetadata", "Test P - Free data", true);

    return 0;
}
