#!/usr/bin/perl
# Copyright (c) 2008 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
#
#  This file is free software: you may copy, redistribute and/or modify it
#  under the terms of the GNU General Public License as published by the
#  Free Software Foundation, either version 2 of the License, or (at your
#  option) any later version.
#
#  This file is distributed in the hope that it will be useful, but
#  WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#  General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.

# ---
#
# User of this file is expected to give a list of files.
# You can run something like: git-diff-index --name-only HEAD
# 
# To install using git, do:

#	chmod o+x .git/hooks/commit-msg
#
# Its recommended your SOB line go below your
# Changes-licensed-under tag.
#
# Your commit-msg script can look like this:
#
# git-diff-index --name-only HEAD | $HOME/bin/ath5k-license.pl >> "$1"
#
# # Uncomment the below to add a Signed-off-by line to the message.
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
#
# # This example catches duplicate Signed-off-by lines.
# test "" = "$(grep '^Signed-off-by: ' "$1" |
#          sort | uniq -c | sed -e '/^[   ]*1[    ]/d')" || {
#                  echo >&2 Duplicate Signed-off-by lines.
#                          exit 1
#                          }

use Switch;
use File::Basename;
use strict;

my $msg_file = shift;

my %ath5k_files = (
	"drivers/net/wireless/ath5k/attach.c" => "ISC",
	"drivers/net/wireless/ath5k/caps.c" => "ISC",
	"drivers/net/wireless/ath5k/desc.c" => "ISC",
	"drivers/net/wireless/ath5k/desc.h" => "ISC",
	"drivers/net/wireless/ath5k/dma.c" => "ISC",
	"drivers/net/wireless/ath5k/eeprom.c" => "ISC",
	"drivers/net/wireless/ath5k/eeprom.h" => "ISC",
	"drivers/net/wireless/ath5k/gpio.c" => "ISC",
	"drivers/net/wireless/ath5k/initvals.c" => "ISC",
	"drivers/net/wireless/ath5k/pcu.c" => "ISC",
	"drivers/net/wireless/ath5k/phy.c" => "ISC",
	"drivers/net/wireless/ath5k/qcu.c" => "ISC",
	"drivers/net/wireless/ath5k/reset.c" => "ISC",
	"drivers/net/wireless/ath5k/reg.h" => "ISC",
	"drivers/net/wireless/ath5k/ath5k.h" => "3-Clause-BSD",
	"drivers/net/wireless/ath5k/base.c" => "3-Clause-BSD",
	"drivers/net/wireless/ath5k/base.h" => "3-Clause-BSD",
	"drivers/net/wireless/ath5k/debug.c" => "GPL",
	"drivers/net/wireless/ath5k/debug.h" => "GPL",
);

my @isc_files = ();
my @bsd_files = ();
my @gpl_files = ();

open(FILES, "git-diff-index --name-only HEAD |") || die "Reading index: $?";

while (<FILES>) {
	chomp;
	if (exists($ath5k_files{$_})) {
		switch ($ath5k_files{$_}) {
			case "ISC" { push (@isc_files, $_) }
			case "3-Clause-BSD" { push (@bsd_files, $_) }
			case "GPL" { push (@gpl_files, $_) }
		}
	}
}
close(FILES);

open (MSG, $msg_file) || die "Could not open msg: $?";
my @msg = <MSG>;
close (MSG);

# holds "Changes-licensed-under" lines
my @changes = ();

my @changed_files = (\@isc_files, \@bsd_files, \@gpl_files); 

# check if all same license
my $types = 0;
foreach my $set (@changed_files) {
	$types++ if (@{$set} > 0);
}

foreach my $new_set (@changed_files) {
	my @array = @$new_set;
	next if (@array == 0);

	my $license = $ath5k_files{$array[0]};

	my @base_names = map { basename($_) } @array;
	# Or something like this... to not use File::Basename
	# @base_names = map { $_ =~ s!^(?:.*/)?(.+?)(?:\.[^.]*)?$!$1! } @array;
	my $set_files = join(", ", @base_names);

	if ($types > 1) {
		push @changes, "Changes to $set_files";
	}

	push @changes, "Changes-licensed-under: $license\n";
}

# read through until s-o-b, put changes just before
open(OUT, ">$msg_file");
my $printed = 0;
foreach my $line (@msg) {
	if ($line =~ /^Signed-off-by:/ && !$printed) {
		print OUT join("\n", @changes), "\n";
		$printed = 1;
	}
	print OUT $line;
}

print OUT "\n", join("\n", @changes) unless $printed;
close(OUT);
