#!/usr/bin/perl -w
# 
# $Id: svn_mk_stats.pl 25 2005-02-17 09:17:58Z written by Hermann Maurer $
# !!! NO WARRANTY !!! You can use the script AS IS WITHOUT ANY WARRANTY !!!
# I'm not resposible for possible corruption or loss of date.
# Feel free to modify or distribute the script.
# 

use strict;
use XML::Simple;
use Data::Dumper;
use Date::Calc qw( Add_Delta_YM Add_Delta_Days Week_of_Year Date_to_Days Monday_of_Week );

my $debug = 0;
my $file = '-';

my $CHANGES_TOTAL      = 0;
my $CHANGES_THIS_WEEK  = 0;
my $CHANGES_LAST_WEEK  = 0;
my $CHANGES_THIS_MONTH = 0;
my $CHANGES_LAST_MONTH = 0;
my $CHANGES_THIS_YEAR  = 0;
my %USERS_TOTAL;
my %USERS_THIS_WEEK;
my %USERS_LAST_WEEK;
my %USERS_THIS_MONTH;
my %USERS_LAST_MONTH;
my %USERS_THIS_YEAR;
my
($TOP3_THIS_WEEK,$TOP3_LAST_WEEK,$TOP3_THIS_MONTH,$TOP3_LAST_MONTH,$TOP3_THIS_YEAR,$TOP3_TOTAL)
= ("", "", "", "", "", "");
my
($FILES_TOTAL,$FILES_THIS_WEEK,$FILES_LAST_WEEK,$FILES_THIS_MONTH,$FILES_LAST_MONTH,$FILES_THIS_YEAR)
= (0,0,0,0,0,0);

my $xs1 = XML::Simple->new();
my $doc = $xs1->XMLin($file);
if ($debug) { warn(Dumper($doc)); }

my ($asec, $amin, $ahou, $aday, $amon, $ayea, $adaw, $adoy, $adst) = localtime(time());
$ayea += 1900; $amon++; $amon = sprintf("%02d", $amon); $aday = sprintf("%02d", $aday);
$amin = sprintf("%02d", $amin); $asec = sprintf("%02d", $asec); $ahou = sprintf("%02d", $ahou);

my ($year,$month,$day,$week);
my ($year1,$month1,$day1,$week1);
my ($today,$this_week_monday,$last_week_monday);
($week,$year) = Week_of_Year($ayea,$amon,$aday);
($year,$month,$day) = Monday_of_Week($week,$year);

$today = Date_to_Days($ayea,$amon,$aday);
$this_week_monday = Date_to_Days($year,$month,$day);

($year1,$month1,$day1) = Add_Delta_Days($year,$month,$day, -7);
$last_week_monday = Date_to_Days($year1,$month1,$day1);

my $this_month_start = Date_to_Days($ayea,$amon,1);
my ($year2,$month2,$day2) = Add_Delta_YM($ayea,$amon,1,0,-1);
my $last_month_start = Date_to_Days($year2,$month2,1);

my $this_year_start = Date_to_Days($ayea,1,1);

my ($cdate,$author);

if ($debug) { 
	warn("actual date and time: $ayea-$amon-$aday $ahou:$amin:$asec \n"); 
	warn("actual week number:   $week\n");
	warn("the monday of the actual week: $year-$month-$day\n");
	warn("the monday of the last   week: $year1-$month1-$day1\n");
	warn("the 1st day of the last month: $year2-$month2-$day2\n");
}

foreach my $entry (@{$doc->{logentry}}) {
	$CHANGES_TOTAL++;
	$cdate = $entry->{'date'};
	$cdate =~ s/T[\d\.\:]*Z$//;
	my ($cy,$cm,$cd) = split(/-/,$cdate);
	my $date = Date_to_Days($cy,$cm,$cd);

	# author stuff
	if (defined($entry->{'author'})) {
		$author= $entry->{'author'};
	}
	else {
		$author = 'nobody';
	}	
	if ($debug) { warn($cdate." ".$author."\n"); }

	if (!defined($USERS_TOTAL{$author})) {
		$USERS_TOTAL{$author} = 1;
	}	
	else {
		$USERS_TOTAL{$author}++;
	}	
	$FILES_TOTAL = files_counter($entry->{'paths'}->{'path'}, $FILES_TOTAL);

	# checks the weeks
	if (($date >= $this_week_monday) && ($date <= $today)) {
		$CHANGES_THIS_WEEK++;
		$FILES_THIS_WEEK = files_counter($entry->{'paths'}->{'path'}, $FILES_THIS_WEEK);
		if (!defined($USERS_THIS_WEEK{$author})) {
			$USERS_THIS_WEEK{$author} = 1;
		}	
		else {
			$USERS_THIS_WEEK{$author}++;
		}	
	}
	if (($date >= $last_week_monday) && ($date <= $last_week_monday + 6)) {
		$CHANGES_LAST_WEEK++;
		$FILES_LAST_WEEK = files_counter($entry->{'paths'}->{'path'}, $FILES_LAST_WEEK);
		if (!defined($USERS_LAST_WEEK{$author})) {
			$USERS_LAST_WEEK{$author} = 1;
		}	
		else {
			$USERS_LAST_WEEK{$author}++;
		}	
	}
	# checks the months
	if (($date >= $this_month_start) && ($date <= $today)) {
		$CHANGES_THIS_MONTH++;
		$FILES_THIS_MONTH = files_counter($entry->{'paths'}->{'path'}, $FILES_THIS_MONTH);
		if (!defined($USERS_THIS_MONTH{$author})) {
			$USERS_THIS_MONTH{$author} = 1;
		}	
		else {
			$USERS_THIS_MONTH{$author}++;
		}	
	}
	if (($date >= $last_month_start) && ($date < $this_month_start)) {
		$CHANGES_LAST_MONTH++;
		$FILES_LAST_MONTH = files_counter($entry->{'paths'}->{'path'}, $FILES_LAST_MONTH);
		if (!defined($USERS_LAST_MONTH{$author})) {
			$USERS_LAST_MONTH{$author} = 1;
		}	
		else {
			$USERS_LAST_MONTH{$author}++;
		}	
	}
	# checks the year
	if (($date >= $this_year_start) && ($date <= $today)) {
		$CHANGES_THIS_YEAR++;
		$FILES_THIS_YEAR = files_counter($entry->{'paths'}->{'path'}, $FILES_THIS_YEAR);
		if (!defined($USERS_THIS_YEAR{$author})) {
			$USERS_THIS_YEAR{$author} = 1;
		}	
		else {
			$USERS_THIS_YEAR{$author}++;
		}	
	}
}

my $j = 0;
foreach my $u (sort {$USERS_TOTAL{$b} <=> $USERS_TOTAL{$a}} keys
%USERS_TOTAL) {
	if ($j < 3) {
		$TOP3_TOTAL .= sprintf $u."(".$USERS_TOTAL{$u}.") ";
	}
	$j++;
}
$j = 0;
foreach my $u (sort {$USERS_THIS_WEEK{$b} <=> $USERS_THIS_WEEK{$a}} keys
%USERS_THIS_WEEK) {
	if ($j < 3) {
		$TOP3_THIS_WEEK .= sprintf $u."(".$USERS_THIS_WEEK{$u}.") ";
	}
	$j++;
}
$j = 0;
foreach my $u (sort {$USERS_LAST_WEEK{$b} <=> $USERS_LAST_WEEK{$a}} keys
%USERS_LAST_WEEK) {
	if ($j < 3) {
		$TOP3_LAST_WEEK .= sprintf $u."(".$USERS_LAST_WEEK{$u}.") ";
	}
	$j++;
}
$j = 0;
foreach my $u (sort {$USERS_THIS_MONTH{$b} <=> $USERS_THIS_MONTH{$a}} keys
%USERS_THIS_MONTH) {
	if ($j < 3) {
		$TOP3_THIS_MONTH .= sprintf $u."(".$USERS_THIS_MONTH{$u}.") ";
	}
	$j++;
}
$j = 0;
foreach my $u (sort {$USERS_LAST_MONTH{$b} <=> $USERS_LAST_MONTH{$a}} keys
%USERS_LAST_MONTH) {
	if ($j < 3) {
		$TOP3_LAST_MONTH .= sprintf $u."(".$USERS_LAST_MONTH{$u}.") ";
	}
	$j++;
}
$j = 0;
foreach my $u (sort {$USERS_THIS_YEAR{$b} <=> $USERS_THIS_YEAR{$a}} keys
%USERS_THIS_YEAR) {
	if ($j < 3) {
		$TOP3_THIS_YEAR .= sprintf $u."(".$USERS_THIS_YEAR{$u}.") ";
	}
	$j++;
}
my $FString1 = "%-15s%10s%10s%10s\t%-20s\n";
my $FString2 = "%-15s%10d%10d%10d\t%-20s\n";

printf($FString1, "", "CHANGES", "FILES", "AUTHORS", "TOP3");
printf($FString2, 
	"This week",  $CHANGES_THIS_WEEK, $FILES_THIS_WEEK, scalar(keys %USERS_THIS_WEEK),
	$TOP3_THIS_WEEK);
printf($FString2, 
	"Last week",  $CHANGES_LAST_WEEK, $FILES_LAST_WEEK, scalar(keys %USERS_LAST_WEEK),
	$TOP3_LAST_WEEK);
printf($FString2, 
	"This month", $CHANGES_THIS_MONTH, $FILES_THIS_MONTH, scalar(keys %USERS_THIS_MONTH),
	$TOP3_THIS_MONTH);
printf($FString2, 
	"Last month", $CHANGES_LAST_MONTH, $FILES_LAST_MONTH, scalar(keys %USERS_LAST_MONTH),
	$TOP3_LAST_MONTH);
printf($FString2, 
	"This year",  $CHANGES_THIS_YEAR, $FILES_THIS_YEAR, scalar(keys %USERS_THIS_YEAR),
	$TOP3_THIS_YEAR);
printf($FString2, 
	"Total",      $CHANGES_TOTAL, $FILES_TOTAL, scalar(keys %USERS_TOTAL),
	$TOP3_TOTAL);

sub files_counter {	
#	my $fentries = $entry->{'paths'}->{'path'};
	my $fentries = shift;
	my $FILES    = shift;
	if (ref($fentries) eq "ARRAY") {
		foreach my $fentry (@{$fentries}) {
			my $content = $fentry->{'content'};
			my $action  = $fentry->{'action'};
			if ($action eq "A") {
				$FILES++;
			}	
			elsif ($action eq "D") {
				$FILES--;
			}	
			if ($debug) { warn($action." ".$content."\n"); }
		}
	}	
	elsif (ref($fentries) eq "HASH") {	
		my $content = $fentries->{'content'};
		my $action  = $fentries->{'action'};
		if ($action eq "A") {
			$FILES++;
		}	
		elsif ($action eq "D") {
			$FILES--;
		}	
		if ($debug) { warn($action." ".$content."\n"); }
	}	
	return $FILES;
}
