#!/usr/bin/perl -w

use strict;

use Getopt::Std;

my $default_log_file = ( -e './server.log' ? './server.log' : 
    '/usr/share/wine-c/nerf/System/server.log');

# Grab the options
my %options;
getopts('hwg:', \%options);
print_usage(), exit
	if ($options{h});
my $web = $options{w};
my $games = $options{g} || 1;
print_usage(), exit
	if ($games !~ /^\d+$/);

my $filename = $ARGV[0] || $default_log_file;

open NERFLOG, "<$filename" or 
	open NERFLOG, "<$filename.log" or
	die "Can't open file " . $filename . "[.log]\n";

my $lastdate = '';
my $lastmap = '(Unknown)';
my $found = 0;
my $maxplayers = 0;
my $cr = "\n";
#$cr = "<br>" . $cr if $web;
my (%userlist, %maplist, %kills, %hours, $username, $startdate, $enddate, 
    $hour);
# Initialize histogram
foreach (0..23) { $hours{$_} = 0 };

while (<NERFLOG>) {
	# If we see anything resembling a date, save it as the closest date
	# we have to the user who joined.
	if (/(\d\d\/\d\d\/\d\d (\d\d):\d\d:\d\d)/) {
		$lastdate = $1;
		$hour = sprintf("%g", $2);
		$startdate = $lastdate unless $startdate;
	}
	if (/LoadMap: (.*)\.nrf/) {
		$lastmap = $1;
	}
	if (/Join succeeded: (.*)$/) {
		chop ($username = $1);
		print "$lastdate - $username\n" unless $web;
		$userlist{$username}++;
		$hours{$hour}++;
		$maxplayers = $hours{$hour} if ($hours{$hour} > $maxplayers);
		$maplist{$lastmap}++;
		$found = 1;
	}
	if (/GameLogger: (.*) knocked/) {
		my $player = $1;
		if ( (/ himself /) or (/ herself /) ) {
			$kills{$player}-- if (exists $kills{$player})
		} else {
			$kills{$player}++;# if (exists $userlist{$player});
		}
	}
}
$enddate = $lastdate;
close NERFLOG;

if ($found) {
	print '<table border=1>' if $web;

	print '<tr>' if $web;
	print_header("Totals: ($startdate - $enddate)", 
	    'colspan=3 align="center" valign="top"');
	print '</td>' if $web;
	print '</tr>' if $web;

	print '<tr>' if $web;

	# User totals
	my $subhead = "";
	$subhead = " (>=$games played)" if ($games > 1);
	print_table(\%userlist, "User Totals$subhead:", 'valign="top"', $games);

	# Kill totals
	print "\n";
	print_table(\%kills, "Knock-out Totals:", 'valign="top"');
	print "\n";

	# Maps played
	print_table(\%maplist, "Maps Played:", 'valign="top"');

	print '</tr>' if $web;

	print '<tr>' if $web;

	# Create a multiplier for the histogram to insure the number
	# of asterisks is <= some maximum
	my $maxstars = 40;
	my $multiplier = 1;
	$multiplier = ($maxstars / $maxplayers) if ($maxplayers > $maxstars);

	print_header("Users by hour:", 'colspan=3 valign="top"');
	print '<pre>' if $web;
	foreach (0..23) {
		printf "%02d: (%4d) ", $_, $hours{$_};
		for (my $i = 1; $i <= ($hours{$_} * $multiplier); $i++) 
			{ print '*' };
		print "${cr}";
	}
	print '</pre>' if $web;
	print "</td></tr></table>\n" if $web;
}

sub print_header
{
	my $string = shift;
	my $modifiers = shift || "";
	$modifiers = ' ' . $modifiers if ($modifiers !~ /^ /);

	print "<td$modifiers>" if $web;
	print $cr unless $web;
	print '<b>' if $web;
	print $string;
	print '</b>' if $web;
	print $cr;
}

sub print_table
{
	my ($table, $title, $modifiers, $minvalue) = @_;
	$minvalue |= 1;

	my $maxlength = 0;
	my $total = 0;

	foreach (keys %{$table}) {
		$maxlength = length $_ if ($maxlength < length $_);
	}

	print_header($title, $modifiers);
	print '<pre>' if $web;
	foreach (sort {
	    ($table->{$b} <=> $table->{$a})
	    ||
	    ((lc $a) cmp (lc $b))
		} keys %{$table}) {
		printf "%-${maxlength}s - %d${cr}", $_, $table->{$_}
		    if ($table->{$_} >= $minvalue);
		$total += $table->{$_};
	}
	print "---${cr}";
	printf "%-${maxlength}s - %d${cr}", 'Total:', $total;
	print '</pre>' if $web;
	print '</td>' if $web;
}

sub print_usage
{
	print <<EOD;
Usage:

nerfusers [-h] [-w] [-g <games>] [<log file>]

-h		Print this help message
-w		Output of statistics suitable for the Web (i.e. HTML)
-g <games>	Restrict output of games played to <games> or more
<log file>	Name of file to report on.  
		Default is $default_log_file
EOD
}
