#include <stdio.h>
#include <stdlib.h>
#include <unixlib.h>
#include <descrip.h>
#include "fast_utc.h"
#include <string.h>
#include <ctype.h>

int LIB$INIT_TIMER(), LIB$SHOW_TIMER(), LIB$STAT_TIMER();

int main ( int argc, char **argv )
{
    static $DESCRIPTOR(source_time,"");
    int status, SYS$BINTIM(), vms_time[2], i, codef, codet, ticks, faults;
    struct tm *gmt, local;
    time_t unix_time, gmt_time;
    /*
     * Convert command line argument to seconds since 1970.
     */
    status = futc_initialize(1);
    printf("status of futc_init: %d\n", status );
    if ( argc < 2 ) { printf("Usage: testutc VMS-timestr\n"); exit(1); }
    for ( i = 0; argv[1][i]; i++ ) argv[1][i] = toupper(argv[1][i]);
    source_time.dsc$w_length = strlen ( argv[1] );
    source_time.dsc$a_pointer = argv[1];

    status = SYS$BINTIM ( &source_time, vms_time );
    printf("Converted argv[1] to VMS binary time, status: %d\n", status );
    if ( (status&1) == 0 ) return status;

    codet = 2;
    codef = 5;
    printf("100,000 iterations for all tests\n");
    LIB$INIT_TIMER();
    for ( i=0; i < 100000; i++ ) unix_time = decc$fix_time ( vms_time );
    LIB$STAT_TIMER ( &codet, &ticks, 0 );
    LIB$STAT_TIMER ( &codef, &faults, 0 );
    printf("Converted VMS time to time_t via decc$fix_time, result: %d\n",
	unix_time );
    printf("   time per iteration: %d usec\n\n", (ticks+5)/10 );
    /*
     * Convert seconds since 1970 to seconds since 1970 GMT.
     */
    LIB$INIT_TIMER();
    for ( i=0; i < 100000; i++ ) gmt_time = futc_local_to_gmt ( unix_time );
    LIB$STAT_TIMER ( &codet, &ticks, 0 );
    LIB$STAT_TIMER ( &codef, &faults, 0 );
    printf( "Converted local time_t to GMT via futc_local_to_gmt, delta: %d\n",
	(unix_time-gmt_time) );
    printf("   time per iteration: %d usec\n\n", (ticks+5)/10 );
    /*
     * Time combination of converting local unix time to GMT time and then
     * converting it to a 'broken down' time, which is what is required to
     * produce a text time string.
     */
    LIB$INIT_TIMER();
    for ( i=0; i < 100000; i++ ) {
        gmt_time = futc_local_to_gmt ( unix_time );
	if ( !(gmt = gmtime ( &gmt_time )) ) break;
    }
    LIB$STAT_TIMER ( &codet, &ticks, 0 );
    LIB$STAT_TIMER ( &codef, &faults, 0 );
    if ( gmt ) printf(
	"gmtime(futc_local_to_gmt(unix_time)) = %d/%d/%d %02d:%02d:%02d\n", 
	gmt->tm_mday, gmt->tm_mon,
	gmt->tm_year+1900, gmt->tm_hour, gmt->tm_min, gmt->tm_sec );
    else printf("error after %d calls to gmtime: %s", i, ctime(&gmt_time) );
    printf("   time per iteration: %d usec\n\n", (ticks+5)/10 );
    /*
     * Time same combination as above, but using mktime instead of futc_*
     */
    gmt = gmtime(&unix_time);
    memcpy ( &local, gmt, sizeof(local) );
    LIB$INIT_TIMER();
    for ( i=0; i < 100000; i++ ) {
        local.tm_isdst = -1;
	gmt_time = mktime(&local);
	if ( !(gmt = gmtime ( &gmt_time )) ) break;
    }
    LIB$STAT_TIMER ( &codet, &ticks, 0 );
    LIB$STAT_TIMER ( &codef, &faults, 0 );
    if ( gmt ) printf("gmtime(mktime(lcl)) = %d/%d/%d %02d:%02d:%02d\n",
	 gmt->tm_mday, gmt->tm_mon,
	gmt->tm_year+1900, gmt->tm_hour, gmt->tm_min, gmt->tm_sec );
    else printf("error after %d calls to localtime\n", i );
    printf("   time per iteration: %d usec\n\n", (ticks+5)/10 );
    /*
     * Time conversion going from GMT time to local broken-down time.
     */
    LIB$INIT_TIMER();
    for ( i=0; i < 100000; i++ ) if ( !(gmt = localtime ( &gmt_time )) ) break;
    LIB$STAT_TIMER ( &codet, &ticks, 0 );
    LIB$STAT_TIMER ( &codef, &faults, 0 );
    if ( gmt ) printf("localtime(gmt_time) = %d/%d/%d %02d:%02d:%02d\n",
	 gmt->tm_mday, gmt->tm_mon,
	gmt->tm_year+1900, gmt->tm_hour, gmt->tm_min, gmt->tm_sec );
    else printf("error after %d calls to localtime\n", i );
    printf("   time per iteration: %d usec\n\n", (ticks+5)/10 );

    return 1;
}
