#!/usr/bin/perl
#
# gitstats.pl - A perl script used to generate data used to generate
#   LOC and other fun graphs.
#

# TODO ability to start at any point in history
# TODO use a unique temp file
# TODO actually delete temp file (read docs on unlink)
# TODO allow specification of an output file
# TODO find clean way to have additional rules

use Switch;

# fill with number of filetypes we are counting
@empty = (0, 0, 0, 0, 0, 0);
# cumulative counters
@total = @empty;
# per commit counters
@lines = @empty;
# output file
$outfile = "/tmp/gitstats.tmp";

# open our git command for reading
open(INPUT, "-|", "git", "log", "--pretty=format:%H %ct", "--reverse", "--numstat") or exit;

# temporary file for data
open(OUTPUT, ">", $outfile) or exit;

# we'll send the data off to gnuplot
open(GP, "|-", "gnuplot") or exit;
print GP <<END;
set term png size 1024,768 linewidth 2
set output 'gitstats.png'
set style data lines
set xdata time
set timefmt "%s"
set format x "%m/%y"
END

# start the "per commit" loop. the first line is a commit hash + date,
# and the last line will be a blank line all by itself.
COMMIT: while(<INPUT>)
{
	chomp;
	# format: "commithash40 epochstamp"
	@firstline = split(/ /);
	@lines = @empty;
	FILE: while(<INPUT>)
	{
		chomp;
		# ensure we didn't have a commit without file changes
		redo COMMIT if /^[0-9a-f]{40}/;
		# once we hit a blank line, this commit is done
		next COMMIT if /^$/;
		# format: "add<tab>del<tab>filename"
		my @fileline = split(/\t/);
		my $diff = $fileline[0] - $fileline[1];
		# add diff to total line count
		$lines[0] += $diff;
		switch($fileline[2]) {
			# don't include translation files in total count
			case /\.pot?$/   { $lines[0] -= $diff; }
			# custom deletions to also do from total count
			case /acinclude\.m4$/ { $lines[0] -= $diff; }
			case /ltmain\.sh$/ { $lines[0] -= $diff; }
			case /config\..*$/ { $lines[0] -= $diff; }
			# custom additions to supplement below
			case /abs(\.in)?$/ { $lines[3] += $diff; }
			case /makepkg(\.in)?$/ { $lines[3] += $diff; }
			case /makeworld(\.in)?$/ { $lines[3] += $diff; }
			case /pacman-optimize(\.in)?$/ { $lines[3] += $diff; }
			case /repo-add(\.in)?$/ { $lines[3] += $diff; }
			case /repo-remove(\.in)?$/ { $lines[3] += $diff; }
			case /gensync(\.in)?$/ { $lines[3] += $diff; }
			case /updatesync(\.in)?$/ { $lines[3] += $diff; }
			case /rankmirrors(\.in)?$/ { $lines[4] += $diff; }
			# general case individual file type line counts
			case /\.c$/      { $lines[1] += $diff; }
			case /\.h$/      { $lines[2] += $diff; }
			case /\.sh(\.in)?$/ { $lines[3] += $diff; }
			case /\.py(\.in)?$/ { $lines[4] += $diff; }
			case /\.txt$/    { $lines[5] += $diff; }
		}
	}
} continue {
	for($i=0; $i<=$#total; $i++) {
		$total[$i] = $total[$i] + $lines[$i];
	}
	# reprint timestamp
	print OUTPUT "$firstline[1] ";
	# print code counts
	print OUTPUT "@total\n"
}
print OUTPUT "e\n";

close(INPUT);
close(OUTPUT);

print GP <<END;
plot '$outfile' u 1:2 t 'Total', \\
     '' u 1:3 t 'C code', \\
     '' u 1:4 t 'Headers', \\
     '' u 1:5 t 'Shell Script', \\
     '' u 1:6 t 'Python', \\
     '' u 1:7 t 'Text Files'
END

close(GP);
unlink($gitstat);

