#! /usr/bin/perl

# renewal_notify - Notify Historical League members of need to renew
# membership.

# Arguments may be given as membership ID numbers, email addresses,
# or filenames.  ID numbers are identified as all numeric, email addresses
# as containing an "@" character, filenames as anything else.  Filenames
# are opened and values in the first column is interpreted as membership
# ID numbers or email addresses (but not, to avoid recursion, as filenames).

# This way you can specify members to notify directly on the command line,
# or you can list members in a file and have the program read the file for
# members to notify.  In particular, the output from need_renewal contains
# membership ID values in the first column.

use DBI;
use strict;

# parse connection parameters from command line if given

use Getopt::Long;
$Getopt::Long::ignorecase = 0; # options are case sensitive

# default parameters - all missing
my ($host_name, $user_name, $password) = (undef, undef, undef);

# GetOptions doesn't seem to allow -uuser_name form, only -u user_name?
GetOptions(
	# =s means a string argument is required after the option
	"host|h=s"      => \$host_name
	,"user|u=s"      => \$user_name
	# :s means a string argument is optional after the option
	,"password|p:s"  => \$password
) or exit (1);

# solicit password if option specified without option value
if (defined ($password) && !$password)
{
	# turn off echoing but don't interfere with STDIN
	open (TTY, "/dev/tty") or die "Cannot open terminal\n";
	system ("stty -echo < /dev/tty");
	print STDERR "Enter password: ";
	chomp ($password = <TTY>);
	system ("stty echo < /dev/tty");
	close (TTY);
	print STDERR "\n";
}

# construct data source
my ($dsn) = "dbi:mysql:samp_db";
$dsn .= ":hostname=$host_name" if $host_name;
$dsn .= ";mysql_read_default_file=$ENV{HOME}/.my.cnf";

# connect to server
my (%attr) = ( RaiseError => 1 );
my ($dbh) = DBI->connect ($dsn, $user_name, $password, \%attr);

# SENDMAIL-PATH
# change path to match your system
my ($sendmail) = "/usr/lib/sendmail -t -oi";
# SENDMAIL-PATH

# MAIN-LOOP
if (@ARGV == 0)		# no arguments, read STDIN for values
{
	read_file (\*STDIN);
}
else
{
	while (my $arg = shift (@ARGV))
	{
		# interpret argument, with filename recursion
		interpret_argument ($arg, 1);
	}
}
# MAIN-LOOP

$dbh->disconnect ();
exit (0);

# READ_FILE
sub read_file
{
my ($fh) = shift;
my ($arg);

	while (defined ($arg = <$fh>))
	{
		# strip off everything past column 1, including newline
		$arg =~ s/\s.*//s;
		# interpret argument, without filename recursion
		interpret_argument ($arg, 0);
	}
}
# READ_FILE

# INTERPRET_ARGUMENT
sub interpret_argument
{
my ($arg, $recurse) = @_;
my ($query, $ary_ref);

	if ($arg =~ /^\d+$/)		# numeric membership ID
	{
		notify_member ($arg);
	}
	elsif ($arg =~ /@/)			# email address
	{
		# get member_id associated with address
		# (there should be exactly one)
		$query = qq{ SELECT member_id FROM member WHERE email = ? };
		$ary_ref = $dbh->selectcol_arrayref ($query, undef, $arg);
		if (scalar (@{$ary_ref}) == 0)
		{
			warn "Email address $arg matches no entry: ignored\n";
		}
		elsif (scalar (@{$ary_ref}) > 1)
		{
			warn "Email address $arg matches multiple entries: ignored\n";
		}
		else
		{
			notify_member ($ary_ref->[0]);
		}
	}
	else						# filename
	{
		if (!$recurse)
		{
			warn "filename $arg inside file: ignored\n";
		}
		else
		{
			open (IN, $arg) or die "Cannot open $arg: $!\n";
			read_file (\*IN);
			close (IN);
		}
	}
}
# INTERPRET_ARGUMENT

# NOTIFY_MEMBER
# notify member that membership will soon be in arrears

sub notify_member
{
my ($member_id) = shift;
my ($query, $sth, $entry_ref, @col_name);

	warn "Notifying $member_id...\n";
	$query = qq{ SELECT * FROM member WHERE member_id = ? };
	$sth = $dbh->prepare ($query);
	$sth->execute ($member_id);
	@col_name = @{$sth->{NAME}};
	$entry_ref = $sth->fetchrow_hashref ();
	$sth->finish ();
	if (!$entry_ref)		# no member found!
	{
		warn "NO ENTRY found for member $member_id!\n";
		return;
	}
	open (OUT, "| $sendmail") or die "Cannot open mailer\n";
	print OUT <<EOF;
To: $entry_ref->{email}
Subject: Your USHL membership is in need of renewal

Greetings.  Your membership in the US Historical League is
due to expire soon.  We hope that you'll take a few minutes to
contact the League office to renew your membership.  The
contents of your member entry are shown below.  Please note
particularly the expiration date.

Thank you.

EOF
	foreach my $col_name (@col_name)
	{
		printf OUT "%s: %s\n", $col_name, $entry_ref->{$col_name};
	}
	close (OUT);
}
# NOTIFY_MEMBER
