/*
 * bbstat.c
 * REPPORTING MODULE FOR BIG BROTHER
 * Sean MacGuire
 * Version 1.9 
 * Mar 13th, 2002
 *
 * (c) Copyright Quest Software, Inc.  1997-2002  All rights reserved.
 *

 *
 * Format: bbstat $BOX $START $END
 * Output: COLOR PCT START END RED%/YEL%/GRE%/PUR%/CLE%/BLU%
 */

#include <stdio.h>
#ifdef TIMEH
#include <time.h>
#else
#include <sys/time.h>
#endif

#include "bb.h"

#define PCTWARN		97

char bbprog[] = "bbstat";

int isvalidline(f1,f2,f3,f4,f5,color,event,duration)
char *f1,*f2,*f3,*f4,*f5,*color;
int event,duration;
{
	if(!strcmp(color,"green")) {
		;
	}
	else if(!strcmp(color,"yellow")) {
		;
	}
	else if(!strcmp(color,"red")) {
		;
	}
	else if(!strcmp(color,"purple")) {
		;
	}
	else if(!strcmp(color,"clear")) {
		;
	}
	else if(!strcmp(color,"blue")) {
		;
	}
	else {
		return(0);
	}

	if( event < 0 || duration < 0 ) {
		return(0);
	}

	if( duration > event ) {
		return(0);
	}

	return(1);
}

int main(argc, argv)
int argc;
char *argv[];
{
	FILE *fp;
	time_t ticks, start, end;
	int first=0;
	int pctwarn=PCTWARN;
	char logfile[4096];
	char *line,*oldline;
	char *pctstr;
	int retc;

	unsigned int red , yel ,  gre , pur , cle , blu;
	unsigned int redcnt , yelcnt ,  grecnt , purcnt , clecnt , blucnt;
	float total, redpct, yelpct, grepct, purpct, clepct, blupct, avail;

	char *f1, *f2, *f3, *f4, *f5, *color, *fstate;
	int event, duration, outofrange;

	red=yel=gre=pur=cle=blu=0;
	redcnt=yelcnt=grecnt=purcnt=clecnt=blucnt=0;

	f1 = (char *)malloc(256);
	f2 = (char *)malloc(256);
	f3 = (char *)malloc(256);
	f4 = (char *)malloc(256);
	f5 = (char *)malloc(256);
	color = (char *)malloc(256);

	if (argc != 4) {
#if DEBUG
		debug("ARG COUNT %d\n", argc);
#endif
		exit(1);
	}
	start = atoi(argv[2]);		/* START TIME */
	end = atoi(argv[3]);		/* END TIME */

	/*
	 * THE LAST EVENT GOES ON 'TILL "NOW"
	 * IF THEY'VE ASKED TO END A REPORT IN THE FUTURE...
	 */
	ticks = time(&ticks);
	if (ticks < end) end = ticks;	/* END NOW */


	line = (char *)malloc(4096);
	oldline = (char *)malloc(4096);

	pctstr=(char *)getenv("BBREPWARN");
	if (pctstr) {
		pctwarn=atoi(pctstr);
		if( (pctwarn < 0) || (pctwarn > 100) ) {
			pctwarn = PCTWARN;
		}
	}

	sprintf(logfile, "%s/%s", (char *)getenv("BBHIST"), argv[1]);

#if DEBUG
	debug("LOGFILE: %s\n", logfile);
#endif

	outofrange = 0;

	fstate = "OK";

	fp = fopen(logfile, "rw");
	if (fp == NULL) exit(2);

	while (fgets(line, 4095, fp)) {

scanline:
		event=duration=0;	/* INITIALIZE */
		f1[0] = f2[0] = f3[0] = f4[0] = f5[0] = '\0';

		retc = sscanf(line, "%256s %256s %256s %256s %256s %256s %d %d", f1,f2,f3,f4,f5,color,&event,&duration);

		/*
		 * HERE'S THE LOGIC TO ADD ALL THIS STUFF UP...
		 */

		if (first == 0) {	/* FIX START TIME TO BE FIRST EVENT */

			/* If there were no stats for the period, make it clear */
			if( event > end ) {
				strcpy(color,"clear");
				duration = 0;
				outofrange = 1;
				break;
			}

			/* If the 1st available stats are after the start period, reset the start period */
			if (event > start) {
				 start = event;
			}

			/* Never redo these tests */
			first = 1;
		}

		/* Was there a duration ? */
		/* Nope, then make sure that it is the last entry in the file */
		if( retc == 7 ) {
			/* Save the current line */
			strcpy(oldline,line);

			/* Try to read another line, if you can then it's */
			/* an invalid line */
			if( fgets(line,4095,fp) ) {
#if DEBUG
				debug("Skipping: %s",oldline);
#endif
				/* go do the sscanf for this new line */
				fstate= "NOTOK";
				goto scanline;
			}
			strcpy(line,oldline);
			if ( end > event ) {
				duration = end - event;
			}
			else {
				duration = 0;
			}
		}
		else {
			if( retc != 8 ) {
#if DEBUG
				debug("Skipping: %s",line);
#endif
				fstate= "NOTOK";
				continue;
			}
		}

		if( !isvalidline(f1,f2,f3,f4,f5,color,event,duration) ) {
#if DEBUG
			debug("Skipping: %s",line);
#endif
			fstate="NOTOK";
			continue;
		}

#if DEBUG
		debug("Calculating: %s",line);
#endif

		/* Does this history file entry relevant to the period ? */
		if ( (event + duration) <= start ) {
			continue;
		}

		/* Does this entry carries over the start period ? */
		/* Then make the entry begin at start, recalculate duration */
		if (event < start) {
			/* ADJUST START */
			duration = (event + duration) - start;
			event = start;
		}

		/* Is the entry is within the period ? */
		if (event >= start && event <= end) {

			/* Does the entry carry over the end period ? */
			if (event + duration > end) { /* ADJUST DURATION */
				duration = end - event;
			}

			/* Make calculations */
			if (strcmp(color, "green") == 0) {
				gre += duration;
				grecnt++;
			}
			else if (strcmp(color, "red") == 0) {
				red += duration;
				redcnt++;
			}
			else if (strcmp(color, "yellow") == 0) {
				yel += duration;
				yelcnt++;
			}
			else if (strcmp(color, "clear") == 0) {
				cle += duration;
				clecnt++;
			}
			else if (strcmp(color, "purple") == 0) {
				pur += duration;
				purcnt++;
			}
			else if (strcmp(color, "blue") == 0) {
				blu += duration;
				blucnt++;
			}
		}

		/* Are we done ? */
		if (event > end) {
			/* It's over */
			break;
		}
#if DEBUG
		debug("%s %d %d\n", color, event, duration);
#endif
	}

#ifdef NOTNEEDED
	if (event < end) {		/* EXTEND THE LAST EVENT */
		duration = end - event;
		if (strcmp(color, "red") == 0) red += duration;
		if (strcmp(color, "yellow") == 0) yel += duration;
		if (strcmp(color, "green") == 0) gre += duration;
		if (strcmp(color, "clear") == 0) cle += duration;
		if (strcmp(color, "purple") == 0) pur += duration;
		if (strcmp(color, "blue") == 0) blu += duration;
	}
#endif

	total = end - start;		/* REAL TOTAL TIME */

	/*
	 * NOW PRINT OUT THE RESULTS
	 */
	redpct = red/(total/100);
	yelpct = yel/(total/100);
	grepct = gre/(total/100);
	clepct = cle/(total/100);
	blupct = blu/(total/100);
	purpct = pur/(total/100);

#if DEBUG
	debug("total: %.0f\n", total);
	debug("red: %d\n", red);
	debug("clear: %d\n", cle);
	debug("green: %d\n", gre);
	debug("yellow: %d\n", yel);
	debug("purple: %d\n", pur);
	debug("blue: %d\n", blu);

	debug("red: %.2f\n", redpct);
	debug("clear: %.2f\n", clepct);
	debug("green: %.2f\n", grepct);
	debug("yellow: %.2f\n", yelpct);
	debug("purple: %.2f\n", purpct);
	debug("blue: %.2f\n", blupct);
#endif

	avail = 100 - redpct;

	/*
	 * SHOW COLORS
	 */
	if (avail > 99.995) {
		if( outofrange == 0 ) {
			printf("green ");
		}
		else {
			printf("clear ");
		}
	}
	else if (avail >= pctwarn) printf("yellow ");
	else printf("red ");

	printf("%.2f ", avail);		/* PRINT AVAILABILITY */
	printf("%d %d ", (int)start, (int)end);	/* PRINT TIME */
	printf("%.2f ", redpct);
	printf("%.2f ", yelpct);
	printf("%.2f ", grepct);
	printf("%.2f ", purpct);
	printf("%.2f ", clepct);
	printf("%.2f ", blupct);
/* SMM CHANGE TO ADD COUNT OF EVENTS
	printf("%s \n", fstate);
*/
	printf("%s ", fstate);
	printf("%d ", redcnt);
	printf("%d ", yelcnt);
	printf("%d ", grecnt);
	printf("%d ", purcnt);
	printf("%d ", clecnt);
	printf("%d\n", blucnt);

	exit(0);
}
