#include "global.h"
#ifdef STATS_USE
#include "stats.h"
#include "stats_u.h"


#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: stats_u.c,v 1.10 1997/07/31 00:44:20 root Exp $";
#endif

long MiscUsers = 0;


static struct use_stats usestats;

static const char usedailyhdr[] = "%10.10s%-34.34sSERVERS\n\n";
static const char useweeklyhdr[] = "%15.15s%-38.38sSERVERS\n\n";
static const char *BBSstr = "BBS";
static const char usagestr[] = "Usage";
static const char usemonthlyhdr[] = "%14.14s%-40.40sSERVERS\n\n";
static const char useyearlyhdr[] = "%4.4s%-21.21sSERVERS\n\n";


static struct cmds STATSusagecmds[] = {
	{ "clear",	doSTATclear_use,0,	0,	NULLCHAR },
	{ "daily",	STATdaily_use,	0,	0,	NULLCHAR },
	{ "general",	STATgeneral_use,0, 	0,	NULLCHAR },
	{ "monthly",	STATmonthly_use,0, 	0,	NULLCHAR },
	{ "weekly",	STATweekly_use,	0, 	0,	NULLCHAR },
	{ "yearly",	STATyearly_use,	0, 	0,	NULLCHAR },
	{ NULLCHAR,	NULL,		0,	0,	NULLCHAR }
};



int
doSTATusage(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	return subcmd(STATSusagecmds,argc,argv,p);
}


int
doSTATclear_use(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
	if(Curproc->input != Command->input)
		tputs (STAT_cannotclear);
	else	{
		memset (&usestats, 0, sizeof (struct use_stats));
		usestats.days = 1;
		usestats.start = time((time_t *)0);
		savestats_use();
		log (-1, "Clearing connection stats");
	}
	return 0;
}


int
STATgeneral_use(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
char buf1[26], buf2[26], buf3[36];
int temp, l, tempdivisor;
int highest[2], second[2];

	tprintf ("\n%26.26s: %-26.26s%-24.24s\n", "USAGE", "BBS", "SERVERS");
	sprintf (buf1, "%ld", usestats.connects[0]);
	sprintf (buf2, "%ld", usestats.connects[1]);
	sprintf (buf3, "Connects since %6.6s", &(ctime(&usestats.start))[4]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n", buf3, buf1, buf2);
	sprintf (buf1, "%ld", usestats.dailyconnects[0]);
	sprintf (buf2, "%ld", usestats.dailyconnects[1]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n", "Connects since midnight",
		buf1, buf2);
	temp = 0;
	if (usestats.connects[0])	{
		tempdivisor = usestats.connects[0] - usestats.dailyconnects[0];
		if (usestats.days > 1 && tempdivisor)
			temp = (int) ((usestats.usage[0] - usestats.day[0] + (tempdivisor - 1)) / tempdivisor);
		else
			temp = (int) (usestats.usage[0] / usestats.connects[0]);
	}
	if (temp > 599)
		sprintf (buf1, "%d hrs, %d min, %d sec", temp / 600, (temp % 600) / 10, ((temp % 600) % 10) * 6);
	else
		sprintf (buf1, "%d min, %d sec", temp / 10, (temp % 10) * 6);
	temp = 0;
	if (usestats.connects[1])	{
		tempdivisor = usestats.connects[1] - usestats.dailyconnects[1];
		if (usestats.days > 1 && tempdivisor)
			temp = (int) ((usestats.usage[1] - usestats.day[1] + (tempdivisor - 1)) / tempdivisor);
		else
			temp = (int) (usestats.usage[1] / usestats.connects[1]);
	}
	if (temp > 599)
		sprintf (buf2, "%d hrs, %d min, %d sec", temp / 600, (temp % 600) / 10, ((temp % 600) % 10) * 6);
	else
		sprintf (buf2, "%d min, %d sec", temp / 10, (temp % 10) * 6);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n", "Average time per connect",
		buf1, buf2);
	sprintf (buf1, "%d", (usestats.days > 1) ? (int)((usestats.connects[0] - usestats.dailyconnects[0] + (usestats.days - 2)) / (usestats.days - 1)) : (int)usestats.connects[0]);
	sprintf (buf2, "%d", (usestats.days > 1) ? (int)((usestats.connects[1] - usestats.dailyconnects[1] + (usestats.days - 2)) / (usestats.days - 1)) : (int)usestats.connects[1]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n", "Average connects per day",
		buf1, buf2);
	highest[0] = highest[1] = -1;
	second[0] = second[1] = -1;
	for (temp = 0; temp < 24; temp++)
		for (l = 0; l < 2; l++)	{
			if (highest[l] == -1 || usestats.hourly[temp][l] > usestats.hourly[highest[l]][l])	{
				second[l] = highest[l];
				highest[l] = temp;
			} else if (second[l] == -1 || usestats.hourly[temp][l] > usestats.hourly[second[l]][l])
				second[l] = temp;
		}
	sprintf (buf1, "At %02d and %02d o'clock", highest[0], second[0]);
	sprintf (buf2, "At %02d and %02d o'clock", highest[1], second[1]);
	tprintf ("%26.26s: %-26.26s%-24.24s\n\n", "Rush hours", buf1, buf2);
	return 0;
}


int
STATdaily_use(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
	tprintf (dailyhdr, usagestr);
	tprintf (usedailyhdr, STAT_emptystr,BBSstr);
	doGraph (24, usestats.hourly);
	tputs (STAT_dailytrailer);
	return 0;
}


int
STATweekly_use(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
	tprintf (weeklyhdr, usagestr);
	tprintf (useweeklyhdr, STAT_emptystr,BBSstr);
	doGraph (7, usestats.daily);
	tputs (STAT_weeklytrailer);
	return 0;
}


int
STATmonthly_use(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
	tprintf (monthlyhdr, usagestr);
	tprintf (usemonthlyhdr, STAT_emptystr,BBSstr);
	doGraph (31, usestats.monthly);
	tputs (STAT_monthlytrailer);
	return 0;
}


int
STATyearly_use(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
	tprintf (yearlyhdr, usagestr);
	tprintf (useyearlyhdr, STAT_emptystr,BBSstr);
	doGraph (12, usestats.yearly);
	tputs (STAT_yearlytrailer);
	return 0;
}


void
STATS_adduse (int which)
{
	if (which < 0 || which > 1)
		return;
	usestats.connects[which]++;
	usestats.dailyconnects[which]++;
}


void
updatestats_use (void)
{
long count;

	usestats.hour[0] += (long) BbsUsers;
	usestats.day[0] += (long) BbsUsers;
	usestats.month[0] += (long) BbsUsers;
	usestats.usage[0] += (long) BbsUsers;
	count = (long) FtpUsers + (long) Tutored + MiscUsers;
#ifdef CONVERS
	count += localConfUsers;
#endif
	usestats.hour[1] += count;
	usestats.day[1] += count;
	usestats.month[1] += count;
	usestats.usage[1] += count;
}


void
loadstats_use(void)
{
FILE *fp;
char buffer[256];

	sprintf (buffer, "%s/usage.dat", STATSDir);
	fp = fopen (buffer, "r");
	if (fp != NULLFILE)	{
		(void) fread (&usestats, sizeof (struct use_stats), 1, fp);
		(void) fclose (fp);
	}
}


void
savestats_use(void)
{
FILE *fp;
char buffer[256];

	sprintf (buffer, "%s/usage.dat", STATSDir);
	fp = fopen (buffer, "w");
	if (fp != NULLFILE)	{
		fwrite (&usestats, sizeof (struct use_stats), 1, fp);
		(void) fclose (fp);
	} else
		log (-1, "Can't open stats file '%s/usage.dat'", STATSDir);
}


void
newhour_use (int hour)
{
	usestats.hourly[hour][0] = usestats.hour[0];
	usestats.hourly[hour][1] = usestats.hour[1];
	usestats.hour[0] = usestats.hour[1] = 0;
}


void
newday_use (int day)
{
	usestats.daily[day][0] = usestats.day[0];
	usestats.daily[day][1] = usestats.day[1];
}


void
endmonthclear_use (int day, int month)
{
int k;
FILE *fp;

	/* clear out non-existent days of last month */
	for (k = day; k < 31; k++)
		usestats.monthly[k][0] = usestats.monthly[k][1] = 0L;
	usestats.yearly[month][0] = usestats.month[0];
	usestats.yearly[month][1] = usestats.month[1];
	fp = tmpfile();
	if (fp)	{
		fprintf (fp, "Monthly Usage Stats for the month of %s: %s\n\n", Months[month], Hostname);
		fprintf (fp, "BBS Usage: %d hrs, %d min, %d sec\n",
			(int)(usestats.month[0] / 600L), (int) ((usestats.month[0] % 600L) / 10L), (int)(((usestats.month[0] % 600L) % 10L) * 6L));
		fprintf (fp, "SERVERS Usage: %d hrs, %d min, %d sec\n",
			(int)(usestats.month[1] / 600L), (int) ((usestats.month[1] % 600L) / 10L), (int)(((usestats.month[1] % 600L) % 10L) * 6L));
		rewind (fp);
		(void) rdaemon (fp, NULLCHAR, NULLCHAR, "sysop", "Monthly Usage Stats", 'P', 0);
		(void) fclose (fp);
	}
	usestats.month[0] = usestats.month[1] = 0;
}


void
endday_use (int day)
{
	usestats.monthly[day][0] = usestats.day[0];
	usestats.monthly[day][1] = usestats.day[1];
	usestats.day[0] = usestats.day[1] = 0;
	usestats.days++;
	usestats.dailyconnects[0] = usestats.dailyconnects[1] = 0;
}


void
eachcycle_use (time_t now)
{
	usestats.last = now;
}


void
init_use (time_t now)
{
	usestats.days = 1;
	usestats.start = now;
}


#endif /* STATS_USE */
