#include "global.h"
#ifdef STATS_TFC
#include "stats.h"
#include "stats_t.h"


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

static struct tfc_stats tfcstats;

static const char tfcdailyhdr[] = "%8.8s%-35.35sPERSONAL\n\n";
static const char tfcdailyhdr2[] = "%10.10s%-32.32sFORWARDED\n\n";
static const char tfcweeklyhdr[] = "%12.12s%-41.41sPERSONAL\n\n";
static const char tfcweeklyhdr2[] = "%15.15s%-37.37sFORWARDED\n\n";
static const char *usagestr = "Traffic";
static const char trafficstr[] = "TRAFFIC";
static const char bulletinstr[] = "BULLETINS";
static const char ntsstr[] = "NTS";
static const char tfcmonthlyhdr[] = "%11.11s%-43.43sPERSONAL\n\n";
static const char tfcmonthlyhdr2[] = "%14.14s%-39.39sFORWARDED\n\n";
static const char tfcyearlyhdr[] = "%2.2s%-23.23sPERSONAL\n\n";
static const char tfcyearlyhdr2[] = "%4.4s%-21.21sFORWARDED\n\n";


static struct cmds STATStrafficcmds[] = {
	{ "clear",	doSTATclear_tfc,0,	0,	NULLCHAR },
	{ "daily",	STATdaily_tfc,	0,	0,	NULLCHAR },
	{ "general",	STATgeneral_tfc,0, 	0,	NULLCHAR },
	{ "monthly",	STATmonthly_tfc,0, 	0,	NULLCHAR },
	{ "weekly",	STATweekly_tfc,	0, 	0,	NULLCHAR },
	{ "yearly",	STATyearly_tfc,	0, 	0,	NULLCHAR },
	{ NULLCHAR,	NULL,		0,	0,	NULLCHAR }
};



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


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


int
STATgeneral_tfc(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
char buf1[26], buf2[26], buf3[36];

	tprintf ("\n%26.26s: %-26.26s%-24.24s\n", trafficstr, bulletinstr, "PERSONAL");
	sprintf (buf1, "%ld", tfcstats.messages[0]);
	sprintf (buf2, "%ld", tfcstats.messages[1]);
	sprintf (buf3, "Traffic since %6.6s", &(ctime(&tfcstats.start))[4]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n", buf3, buf1, buf2);
	sprintf (buf1, "%ld", tfcstats.day[0]);
	sprintf (buf2, "%ld", tfcstats.day[1]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n", "Traffic since midnight",
		buf1, buf2);
	sprintf (buf1, "%ld", tfcstats.hour[0]);
	sprintf (buf2, "%ld", tfcstats.hour[1]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n", "Traffic this hour",
		buf1, buf2);
	sprintf (buf1, "%d", (tfcstats.days > 1) ? (int)((tfcstats.messages[0] - tfcstats.day[0] + (tfcstats.days - 2)) / (tfcstats.days - 1)) : (int)tfcstats.messages[0]);
	sprintf (buf2, "%d", (tfcstats.days > 1) ? (int)((tfcstats.messages[1] - tfcstats.day[1] + (tfcstats.days - 2)) / (tfcstats.days - 1)) : (int)tfcstats.messages[1]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n\n", "Average traffic per day",
		buf1, buf2);

	tprintf ("\n%26.26s: %-26.26s%-24.24s\n", trafficstr, ntsstr, "FORWARDED");
	sprintf (buf1, "%ld", tfcstats.messages2[0]);
	sprintf (buf2, "%ld", tfcstats.messages2[1]);
	sprintf (buf3, "Traffic since %6.6s", &(ctime(&tfcstats.start))[4]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n", buf3, buf1, buf2);
	sprintf (buf1, "%ld", tfcstats.day2[0]);
	sprintf (buf2, "%ld", tfcstats.day2[1]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n", "Traffic since midnight",
		buf1, buf2);
	sprintf (buf1, "%ld", tfcstats.hour2[0]);
	sprintf (buf2, "%ld", tfcstats.hour2[1]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n", "Traffic this hour",
		buf1, buf2);
	sprintf (buf1, "%d", (tfcstats.days > 1) ? (int)((tfcstats.messages2[0] - tfcstats.day2[0] + (tfcstats.days - 2)) / (tfcstats.days - 1)) : (int)tfcstats.messages2[0]);
	sprintf (buf2, "%d", (tfcstats.days > 1) ? (int)((tfcstats.messages2[1] - tfcstats.day2[1] + (tfcstats.days - 2)) / (tfcstats.days - 1)) : (int)tfcstats.messages2[1]);
	tprintf ("  %24.24s: %-26.26s%-24.24s\n\n", "Average traffic per day",
		buf1, buf2);

	return 0;
}


int
STATdaily_tfc(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
	tprintf (dailyhdr, usagestr);
	tprintf (tfcdailyhdr, STAT_emptystr,bulletinstr);
	doGraph (24, tfcstats.hourly);
	tputs (STAT_dailytrailer);
	tprintf (tfcdailyhdr2, STAT_emptystr,ntsstr);
	doGraph (24, tfcstats.hourly2);
	tputs (STAT_dailytrailer);
	return 0;
}


int
STATweekly_tfc(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
	tprintf (weeklyhdr, usagestr);
	tprintf (tfcweeklyhdr, STAT_emptystr,bulletinstr);
	doGraph (7, tfcstats.daily);
	tputs (STAT_weeklytrailer);
	tprintf (tfcweeklyhdr2, STAT_emptystr,ntsstr);
	doGraph (7, tfcstats.daily2);
	tputs (STAT_weeklytrailer);
	return 0;
}


int
STATmonthly_tfc(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
	tprintf (monthlyhdr, usagestr);
	tprintf (tfcmonthlyhdr, STAT_emptystr,bulletinstr);
	doGraph (31, tfcstats.monthly);
	tputs (STAT_monthlytrailer);
	tprintf (tfcmonthlyhdr2, STAT_emptystr,ntsstr);
	doGraph (31, tfcstats.monthly2);
	tputs (STAT_monthlytrailer);
	return 0;
}


int
STATyearly_tfc(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
	tprintf (yearlyhdr, usagestr);
	tprintf (tfcyearlyhdr, STAT_emptystr,bulletinstr);
	doGraph (12, tfcstats.yearly);
	tputs (STAT_yearlytrailer);
	tprintf (tfcyearlyhdr2, STAT_emptystr,ntsstr);
	doGraph (12, tfcstats.yearly2);
	tputs (STAT_yearlytrailer);
	return 0;
}


void
STATS_addtfc (int which, int amount)
{
	if (which < 0 || which > 3)
		return;
	if (which < 2)	{
		which %= 2;
		tfcstats.messages[which] += amount;
		tfcstats.hour[which] += amount;
		tfcstats.day[which] += amount;
		tfcstats.month[which] += amount;
	} else	{
		which %= 2;
		tfcstats.messages2[which] += amount;
		tfcstats.hour2[which] += amount;
		tfcstats.day2[which] += amount;
		tfcstats.month2[which] += amount;
	}
}


void
updatestats_tfc (void)
{
	/* nothing, at this time - addtfcstats() does all the work */
}


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

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


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

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


void
newhour_tfc (int hour)
{
	tfcstats.hourly[hour][0] = tfcstats.hour[0];
	tfcstats.hourly[hour][1] = tfcstats.hour[1];
	tfcstats.hour[0] = tfcstats.hour[1] = 0;
	tfcstats.hourly2[hour][0] = tfcstats.hour2[0];
	tfcstats.hourly2[hour][1] = tfcstats.hour2[1];
	tfcstats.hour2[0] = tfcstats.hour2[1] = 0;
}


void
newday_tfc (int day)
{
	tfcstats.daily[day][0] = tfcstats.day[0];
	tfcstats.daily[day][1] = tfcstats.day[1];
	tfcstats.daily2[day][0] = tfcstats.day2[0];
	tfcstats.daily2[day][1] = tfcstats.day2[1];
}


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

	/* clear out non-existent days of last month */
	for (k = day; k < 31; k++)	{
		tfcstats.monthly[k][0] = tfcstats.monthly[k][1] = 0L;
		tfcstats.monthly2[k][0] = tfcstats.monthly2[k][1] = 0L;
	}
	tfcstats.yearly[month][0] = tfcstats.month[0];
	tfcstats.yearly[month][1] = tfcstats.month[1];
	tfcstats.yearly2[month][0] = tfcstats.month2[0];
	tfcstats.yearly2[month][1] = tfcstats.month2[1];
	fp = tmpfile();
	if (fp)		{
		fprintf (fp, "Monthly Traffic Stats for the month of %s: %s\n\n", Months[month], Hostname);
		fprintf (fp, "Bulletins: %ld\nPersonal: %ld\nNTS: %ld\nForwarded: %ld\n",
			tfcstats.month[0], tfcstats.month[1], tfcstats.month2[0], tfcstats.month2[1]);
		rewind (fp);
		(void) rdaemon (fp, NULLCHAR, NULLCHAR, "sysop", "Monthly Traffic Stats", 'P', 0);
		(void) fclose (fp);
	}
	tfcstats.month[0] = tfcstats.month[1] = 0;
	tfcstats.month2[0] = tfcstats.month2[1] = 0;
}


void
endday_tfc (int day)
{
	tfcstats.monthly[day][0] = tfcstats.day[0];
	tfcstats.monthly[day][1] = tfcstats.day[1];
	tfcstats.day[0] = tfcstats.day[1] = 0;
	tfcstats.monthly2[day][0] = tfcstats.day2[0];
	tfcstats.monthly2[day][1] = tfcstats.day2[1];
	tfcstats.day2[0] = tfcstats.day2[1] = 0;
	tfcstats.days++;
}


void
eachcycle_tfc (time_t now)
{
	tfcstats.last = now;
}


void
init_tfc (time_t now)
{
	tfcstats.days = 1;
	tfcstats.start = now;
}


#endif /* STATS_TFC */
