#!/usr/bin/perl

use File::Basename;
use File::Temp qw/tempdir/;
use Getopt::Std;

getopts('nhyv');

if ($opt_h) {
  print <<EOF
Usage: $0 [ -n ] [ -y ] [ -v ] [ -h ] <repo> <rev>

-n: do not send the email
-y: assume yes to all questions
-v: be verbose
-h: this help

<repo> the SVN repository to look into
<rev> the revision to look at
EOF
;
  exit(1);
}

$template_text = "$ENV{HOME}/.process_pay_message.conf";
if (!-e $template_text) {
  $template_text = "/dev/null";
}
# used by mutt to set the default From: header
$ENV{'EMAIL'} = 'Pay script <comptabilite@koumbit.org>';
$mailer = "/usr/bin/mutt -i $template_text -x -n -e 'set record=\"\"' -s '%s' -a '%s' -- '%s' < /dev/null";

# no good path is set in the hook caller
$ENV{'PATH'} = '/usr/bin:/bin';

# allow users to override the SVNBASE
require "$ENV{HOME}/.process_pay.conf" if -f "$ENV{HOME}/.process_pay.conf";

# we expect this to set $YEAR (2010-2011) and $COMPANY (RP12345)
require "/etc/process_pay.conf" if -f "/etc/process_pay.conf";

# information provided throught he hook
$REPO=$ARGV[0];
$REV=$ARGV[1];

$opt_y || print qq|
< << <<< Crude desjardins pay processing assistant, welcome! >>> >> >

This will assist you with various tedious tasks. I expect to find some
.pdf files extracted from the Desjardins service in the current
directory (or the directory you gave me as an argument). I will process
them, place them in SVN and commit them, mail them to the right users
and then finish.

Configuration for this script is in the script itself so edit it with a
text editor to change the following parameters:

COMPANY: $COMPANY
MAILER: $mailer

Press ENTER to continue or control-c to abort.
|;

$opt_y || <STDIN>;

$| = 1;

# spool directory, created as a temp dir only if we process stuff
$spool = 0;

# look at the revision to see if we added the right zip file
my $svnlook_changed = "svnlook changed '$REPO' -r '$REV'";
$opt_v && print "running: $svnlook_changed\n";
foreach my $file (`$svnlook_changed`) {
  if ($file =~ m/^A\s+(finances\/rapports-paie\/${YEAR}\/RP_${COMPANY}_[^.]*\.zip)\s+$/) {
    if (!$spool) {
      $spool = tempdir( CLEANUP => 1 );
    }
    my $zipfile = basename($1);
    my $svnlook_cat = "/usr/bin/svnlook cat -r '$REV' '$REPO' '$1' > $spool/$zipfile";
    $opt_v && print "running: " . $svnlook_cat . "\n";
    system($svnlook_cat);
    process_zipfile("$spool/$zipfile");
  }
}

# process a group of stubs, which are zip files of PDF files
sub process_zipfile($) {
  my $stubs = shift;
  if (!-e $stubs) {
    warn("cannot find stub $stubs");
    return;
  }
  # list the content of the file and ask confirmation
  $opt_v && print "zip file found, content:\n";
  $opt_v && system("/usr/bin/unzip -l \"$stubs\"");
  $opt_y || print "Process $stubs? ";
  if (!($opt_y || <STDIN> =~ m/y(es)?/i)) {
    return;
  }

  $dir = $stubs;
  $dir =~ s/\.zip$//;
  $cmd = "/usr/bin/unzip -d '$dir' -n '$stubs'";
  if ($opt_v) {
    print "running: $cmd\n";
  } else {
    $cmd .= "> /dev/null";
  }
  system($cmd) == 0
    or warn("cannot unzip $stubs\n");

  # iterate over the files in the archive
  foreach my $stub (glob("$dir/RELEVE_PAIE_*.pdf")) {
    process_stub($stub);
  }
}

sub process_stub($) {
    $stub = shift;
      $report = basename($stub);
      if ($report =~ m/RELEVE_PAIE_\d+_0*(\d+)_\d+_\d+.pdf/) {
          $employee_id = $1;
          # Silently ignore stubs that are not configured.
          if (! defined($EMPLOYEES{$employee_id})) {
              print "Stub \"$stub\" for employee $employee_id is not configured. Ignoring pay stub.";
              return;
          }
          $employee = $EMPLOYEES{$employee_id};
      }
      $opt_y || print "found paycheck \"$stub\" for employee $employee_id ($employee), proceed? ";
      if ($opt_y || <STDIN> =~ m/y(es)?/i) {
	# the actual attachment sent by email, might be different from
	# the stub if compressed, crypted, etc. (for now we just crypt)
	my $attach = $stub;
        my $pgp_cmd = "/usr/bin/gpg ";
        if ($opt_y) {
          $pgp_cmd .= "--batch --yes ";
        }
        $pgp_cmd .= "--auto-key-locate keyserver -r '$employee' -e '$stub'";
        if (!$opt_v) {
          $pgp_cmd .= "> /dev/null";
        }
	if (system($pgp_cmd) == 0) {
	  $gpg = 1;
	  $attach .= '.gpg';
          $opt_v && print "crypted mail\n";
	} else {
	  $gpg = 0;
	  unlink("$stub.gpg");
	  warn("can't crypt the attachment to $employee, mailed in plain text\n");
	}
	# send the thing by email
        $mail_cmd = sprintf($mailer, ("Paycheck $stub", $attach, $employee));
        if ($opt_n || (system($mail_cmd) == 0)) {
          $opt_v && print "sent email to $employee\n";
        } else {
            warn("can't send stub by email\n");
        }
      } else {
        print "okay, not processing";
      }
}
