/*
 *	report.c	1.0	18-Mar-91	EHK	Just prints some values
 *	report.c	1.3	02-Apr-91	EHK	Now nice reports
 *	report.c	1.4	03-Jan-92	EHK	NNTPXFER report added
 *	report.c	1.4b	04-Jan-92	EHK	Assertions added (any?)
 */

#include "nestor.h"


/*
 *---------------------------------------------------------------------------
 *	ANYTHING_AT_ALL	- see if there's anything to do at all.
 *			  Assertion on a certain positive (ptr->value)
 *---------------------------------------------------------------------------
 */
#define ANYTHING_AT_ALL(ptr,which)				\
	for ( ptr = nntps ; ; )					\
		if ( ptr->which )				\
			break;					\
		else						\
			if ( ++ptr == nntps + num_nntp_hosts )	\
				return



/*
 *---------------------------------------------------------------------------
 *	Report_nntpd	- generate a nice report on incoming traffic
 *---------------------------------------------------------------------------
 */
int
Report_nntpd()
{
	register nntp_t	*np;

	ANYTHING_AT_ALL(np,recv_a_acc);		/* any accepted?	*/

	printf("\n\n\
                    *** Incoming Articles Via NntpDaemon ***\
	\n\n");

	printf("%-24.24s %8s %7s %7s %9s %9s %9s\n",
		"News Site", "Accept", "Reject", "Failed",
		"usr cpu", "sys cpu", "elapsed");

	for ( np = nntps ; np < nntps + num_nntp_hosts ; np++ )
	{
		if ( np->recv_a_acc )		/* accept anything btw?	*/
		{
			printf("%-24.24s %8d %7d %7d %9s %9s %9s\n",
				np->nntp_host,
				np->recv_a_acc,
				np->recv_a_rej,
				np->recv_a_fai,
				HHMMSS(np->recv_u_cpu),
				HHMMSS(np->recv_s_cpu),
				HHMMSS(np->recv_r_cpu));
		}
	}

}

/*
 *---------------------------------------------------------------------------
 *	Report_nntpxmit	- generate a nice report on outgoing NNTPXMIT traffic
 *---------------------------------------------------------------------------
 */
int
Report_nntpxmit()
{
	register nntp_t	*np;

	ANYTHING_AT_ALL(np,xmit_a_off);		/* any XMIT offered?	*/

	printf("\n\n\
                    *** Outgoing Articles Via NntpXmit ***\
	\n\n");

	printf("%-23.23s %6s %6s %6s %4s %9s %9s %9s\n",
		"News Site", "Offer", "Accept", "Reject", "Fail",
		"usr cpu", "sys cpu", "elapsed");

	for ( np = nntps ; np < nntps + num_nntp_hosts ; np++ )
	{
		if ( np->xmit_a_off )
		{
			printf("%-23.23s %6d %6d %6d %4d %9s %9s %9s\n",
				np->nntp_host,
				np->xmit_a_off,
				np->xmit_a_acc,
				np->xmit_a_rej,
				np->xmit_a_fai,
				HHMMSS(np->xmit_u_cpu),
				HHMMSS(np->xmit_s_cpu),
				HHMMSS(np->xmit_r_cpu));
		}
	}
}

/*
 *---------------------------------------------------------------------------
 *	Report_nntpxfer	- generate a nice report on outgoing NNTPXFER traffic
 *---------------------------------------------------------------------------
 */
int
Report_nntpxfer()
{
	register nntp_t	*np;

	ANYTHING_AT_ALL(np,xfer_a_off);		/* any XFER offered?	*/

	printf("\n\n\
                    *** Outgoing Articles Via NntpXfer ***\
	\n\n");

	printf("%-23.23s %6s %6s\n",
		"News Site", "Offer", "Accept");

	for ( np = nntps ; np < nntps + num_nntp_hosts ; np++ )
	{
		if ( np->xfer_a_off )
		{
			printf("%-23.23s %6d %6d\n",
				np->nntp_host,
				np->xfer_a_off,
				np->xfer_a_acc);
		}
	}
}

/*
 *---------------------------------------------------------------------------
 *	Report_network	- show network connections/failures
 *---------------------------------------------------------------------------
 */
int
Report_network()
{
	register nntp_t	*np;

	printf("\n\n\
                    *** Overall Network Connections Report ***\
	\n\n");

	printf("\
Network Connections       -------- Incoming -------   -------- Outgoing -------\
	\n");

	printf("%-23.23s %7s %9s %9s %7s %9s %8s\n",
		"News Site", "#conn", "#lsyserr", "#neterr",
		"#conn", "#rsyserr", "#neterr");

	for ( np = nntps ; np < nntps + num_nntp_hosts ; np++ )
	{
		printf("%-23.23s %7d %9d %9d %7d %9d %8d %c\n",
			np->nntp_host,
			np->recv_n_connect,
			np->recv_n_hostfail, np->recv_n_netfail,
			np->xmit_n_connect,
			np->xmit_n_hostfail, np->xmit_n_netfail,
			np->recv_n_connect && !np->recv_a_acc ? '*' : ' ');
	}
}

/*
 *---------------------------------------------------------------------------
 *	Report_remote	- show remote readership/postings stats
 *---------------------------------------------------------------------------
 */
int
Report_remote()
{
	register nntp_t	*np;

	printf("\n\n\
                    *** Remote Clients Usage Report ***\
	\n\n");

	printf("\
Remote Readerships        --- Reading ---       ---------- Postings ----------\
	\n");

	printf("%-23.23s %8s %8s     %10s %10s %10s\n",
		"News Site", "groups", "articles",
		"#succeed", "#reject", "#fail");

	for ( np = nntps ; np < nntps + num_nntp_hosts ; np++ )
	{
		if ( np->recv_rr_grp || np->recv_rr_art ||
		     np->recv_p_acc  || np->recv_p_rej  || np->recv_p_fai )
			printf("%-23.23s %8d %8d     %10d %10d %10d\n",
				np->nntp_host,
				np->recv_rr_grp, np->recv_rr_art,
				np->recv_p_acc, np->recv_p_rej, np->recv_p_fai);
	}
}

/*
 *---------------------------------------------------------------------------
 *	Report_smart	- a bit more than just figures, like trying to tell
 *			  how well/bad certain links perform etc.
 *---------------------------------------------------------------------------
 */
int
Report_smart()
{
	register nntp_t	*np;
	int	total_conn,
		total_fail;
	float	percent;
	char	*class,
		*not_avail = "n/a";

	printf("\n\n\
                    *** Overall Performance Averages ***\
	\n\n");

	printf("\
Performance Quality       --- Articles/Second ---     ----- Network Link -----\
	\n");

	printf("%-23.23s %10s       %8s     %8s  %14s\n",
		"News Site", "incoming", "outgoing",
		"%-failed", "classification");

	for ( np = nntps ; np < nntps + num_nntp_hosts ; np++ )
	{
		total_conn = np->recv_n_connect + np->xmit_n_connect;
		total_fail = np->recv_n_netfail + np->xmit_n_netfail;

		if ( total_conn == 0 )
			percent = -1;		/* not available	*/
		else
		  if ( total_fail == 0 )	/* it's pretty good	*/
			percent = 0;
		  else
		    percent = ((float) total_fail /
		   	      ((float) total_conn + (float) total_fail)) * 100;

		if ( percent > 25 )
			class = "bad";
		else
			if ( percent > 10 )
				class = "moderate";
			else
				if ( percent > 3 )
					class = "good";
				else
					if ( percent >= 0 )
						class = "excellent";
					else
						class = not_avail;

		printf("%-23.23s ", np->nntp_host);
		if ( np->recv_a_acc )
			printf("%10.2f", np->recv_a_acc / np->recv_r_cpu);
		else
			printf("%10s", not_avail);

		if ( np->xmit_a_acc )
			printf("%15.2f", np->xmit_a_acc / np->xmit_r_cpu);
		else
			printf("%15s", not_avail);

		if ( percent < 0 )
			printf("%13s", not_avail);
		else
			printf("%12.2f%%", percent);
		
		printf("%16s\n", class);
	}
}
