
/*
 * LAGHIST.C	(C)Copyright 1996, Matthew Dillon
 *		Permission granted to freely redistribute this code 
 *		as long as names of authors and copyright notices
 *		are kept intact.  Permission granted to use portions
 *		of this code in your own projects without any 
 *		attached liability.
 *
 * LAGHIST -h -i 1h < /usr/lib/news/history
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define arysize(ary)	(sizeof(ary)/sizeof((ary)[0]))

int HistoTtl[24];
int HistoCnt[24];
int Histogram[24];
int DoHist = 0;
int DoLag = -1;

char *showdate(time_t t);

int
main(int ac, char **av)
{
    char buf[1024];
    time_t t =  time(NULL);
    int total = 0;
    int count = 0;
    int interval = 24 * 60;
    int hinterval = 10;
    int printSlots = -1;
    int totalHCnt = 0;

    {
	int i;

	for (i = 1; i < ac; ++i) {
	    char *ptr = av[i];

	    if (*ptr == '-') {
		ptr += 2;
		switch(ptr[-1]) {
		case 'h':
		    DoHist = 1;
		    if (DoLag < 0)
			DoLag = 0;
		    if (*ptr) {
			hinterval = strtol(ptr, &ptr, 0);
			switch(*ptr) {
			case 'm':
			    break;
			case 'h':
			    hinterval *= 60;
			    break;
			case 'd':
			    hinterval *= 24 * 60;
			    break;
			}
		    }
		    break;
		case 'l':
		    DoLag = 1;
		    break;
		case 'p':
		    ptr = (*ptr) ? ptr : av[++i];
		    printSlots = strtol(ptr, &ptr, 0);
		    break;
		case 'i':
		    ptr = (*ptr) ? ptr : av[++i];
		    interval = strtol(ptr, &ptr, 0);
		    switch(*ptr) {
		    case 'm':
			break;
		    case 'h':
			interval *= 60;
			break;
		    case 'd':
			interval *= 24 * 60;
			break;
		    }
		    break;
		}
	    }
	}
    }

    t = (time_t)((unsigned long)t - (unsigned long)t % (interval * 60));

    while (fgets(buf, sizeof(buf), stdin) != NULL) {
	char *ptr;

	if ((ptr = strtok(buf, " \t\n")) != NULL) {
	    if ((ptr = strtok(NULL, " \t\n")) != NULL) {
		char *p1;
		char *p2;
		char *p3;

		if ((p1 = strtok(ptr, "~")) != NULL &&
		    (p2 = strtok(NULL, "~")) != NULL &&
		    (p3 = strtok(NULL, "~")) != NULL
		) {
		    long t1 = strtoul(p1, NULL, 0);
		    long t2 = strtoul(p3, NULL, 0);
		    long dt = (t1 - t2) / 60;
		    long slot = (t - t1) / 60 / interval;

		    if (dt >= 0 && dt / hinterval < arysize(Histogram))
			++Histogram[dt/hinterval];
		    if (dt >= 0 && dt < 30 * 24 * 60)
			++totalHCnt;

		    if (dt >= 0 && dt < 30 * 24 * 60 && slot >= 0 && slot < arysize(HistoTtl)) {
			if (slot < 24) {
			    total += dt;
			    count += 1;
			}

			HistoTtl[slot] += dt;
			HistoCnt[slot] += 1;
		    }
		}
	    }
	}
    }
    if (DoLag) {
	int i;

	for (i = 0; i < arysize(HistoCnt) && (printSlots < 0 || i < printSlots); ++i) {
	    if (HistoCnt[i] > 10) {
		int lag = HistoTtl[i] / HistoCnt[i];
		printf("News lag for %s: %d days %2d hours %2d minutes\n",
		    showdate(t - i * interval * 60),
		    lag / (60 * 24),
		    lag / 60 % 24,
		    lag % 60
		);
	    }
	}
    }
    if (DoHist) {
	int i;
	int total = 0;

	printf("\nArtricle lag Histogram over sample size of %d\n", totalHCnt);

	for (i = 0; i < arysize(Histogram); ++i) {
	    total += Histogram[i];
	    printf(" %d\t(%3d.%02d%% / %3d.%02d%%) %4d min\n", 
		Histogram[i],
		Histogram[i] * 100 / totalHCnt,
		Histogram[i] * 10000 / totalHCnt % 100,
		total * 100 / totalHCnt,
		total * 10000 / totalHCnt % 100,
		hinterval * (i + 1)
	    );
	}
    }
    exit(0);
}

char *
showdate(time_t t)
{
    struct tm *tp = localtime(&t);
    static char buf[64];

    strftime(buf, sizeof(buf), "%a %d %b %H:%M", tp);
    return(buf);
}

