#!/usr/bin/perl
#  Copyright 2001-2018 Leslie Richardson

#  This file is part of Open Admin for Schools.

#  Open Admin for Schools is free software; you can redistribute it 
#  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.


my %lex = ('Group Email' => 'Group Email',
	   'Grade' => 'Grade',
	   'Homeroom' => 'Homeroom',
	   'Main' => 'Main',
	   'Blank=All' => 'Blank=All',
	   'Select' => 'Select',
	   'Values' => 'Values',
	   'Group' => 'Group',
	   'Parent' => 'Parent',
	   'Separate with Spaces' => 'Separate with Spaces',
	   'Subject' => 'Subject',
	   'Message' => 'Message',
	   'Continue' => 'Continue',
	   'Student' => 'Student',
	   'Checked' => 'Checked',
	   'Email Sent' => 'Email Sent',
	   'Error' => 'Error',
	   'Email' => 'Email',
	   'Attach File' => 'Attach File',
	   'Cannot open file' => 'Cannot open file',
	   'Maximum File Upload size exceeded!' => 'Maximum File Upload size exceeded!',
	   'Next Page' => 'Next Page',
	   'Form' => 'Form',
	   'Forms' => 'Forms',
	   'OR' => 'OR',
	   
	   );

my $self = 'emailgroup1.pl';

# Configured Values
my $maxbufcount = 1000; # 1000K = 1Mb limit for file attach size.

#my $mailserver = 'richtech.ca'; # localhost
#my $noreplyName = 'OpenAdmin Messaging System';
#my $noreplyEmail = 'no-reply@yoursite.net';

# New config values in conf_system.
my $g_EmailAuthId = '';
my $g_EmailAuthPwd = '';
my $g_EmailPort = 587; # or 587 for TLS
my $g_EmailServer = 'email-smtp.us-east-1.amazonaws.com';
my $g_EmailNoReply = 'no-reply@conventhighschool.org';
my $g_EmailUseTLS = '1'; # use 1 or 0 (zero)


use CGI;
use DBI;
# The Email libraries are found in the postEmail sub.


# calc current date
my @tim = localtime(time);
my $year = @tim[5] + 1900;
my $month = @tim[4] + 1;
my $day = @tim[3];
my $currdate = "$year-$month-$day";

eval require "../etc/admin.conf";
if ( $@ ) {
    print $lex{Error}. " :$@<br>\n";
    die $lex{Error}. " :$@<br>\n";
}

my $schoolmode;
if ( $g_BritishSchoolMode ) {
    $schoolmode = 1; # will there be a mode 2?
}

my $q = new CGI;
print $q->header( -charset, $charset ); 
my %arr = $q->Vars;

my $checked = $arr{checked};
delete $arr{checked};


my $dsn = "DBI:$dbtype:dbname=$dbase";
my $dbh = DBI->connect($dsn,$user,$password);
$dbh->{mysql_enable_utf8} = 1;

# Show page Header
my $title = $lex{'Group Email'};
print qq{$doctype\n<html><head><title>$title</title>\n};
print qq{<link rel="stylesheet" href="$css" type="text/css">\n};
print qq{$chartype\n</head><body style="padding:1em;">\n};

print qq{[ <a href="$homepage">$lex{Main}</a> ]\n};
print qq{<h1>$title</h1>\n};

if ( not $arr{page} ) { # Select Groups and which emails to do (Student, Parents)
    showStartPage();

} elsif ( $arr{page} == 1 ) { # Select Students, Parents / Set Message, Attachment
    delete $arr{page};
    selectRecipients();

} elsif ( $arr{page} == 2 ) { # post the Mail
    delete $arr{page};
    postEmail();

}
 


#----------------
sub showStartPage {
#----------------

    my (@homerooms, @grades );
    # Get Homerooms
    my $sth = $dbh->prepare("select distinct homeroom from student 
      where homeroom is not NULL and homeroom != ''");
    $sth->execute;
    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
    while ( my $hr = $sth->fetchrow ) {
	push @homerooms, $hr;
    }
    @homerooms = sort {$a <=> $b} @homerooms;

    # Get Grades
    $sth = $dbh->prepare("select distinct grade from student 
      where grade is not NULL and grade != ''");
    $sth->execute;
    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
    while ( my $gr = $sth->fetchrow ) {
	push @grades, $gr;
    }
    @grades = sort {$a <=> $b} @grades;


    # Setup the form and start of table.
    print qq{<form action="$self" method="post">\n};
    print qq{<input type="hidden" name="page" value="1">\n};
    
    print qq{<table cellpadding="3" cellspacing="0" border="0" };
    print qq{style="margin-bottom:0.4em; border:1px solid gray;padding:0.3em;">\n};
    
    # Grades
    print qq{<tr><td class="bra">$lex{Select} $lex{Grade}};
    if ( $schoolmode == 1 ) {
	print qq{/$lex{Forms}};
    }
    print qq{</td>};
    print qq{<td class="la">};
    
    foreach my $gr ( sort {$a <=> $b} @grades ) {
	my $displaygrade = $gr;
	if ( $schoolmode == 1 ) { # British mode
	    my $val = $g_FormMap{$gr};
	    if ( not $val ) { $val = $gr; }
	    if ( $val =~ m/F|f/ ) { # we are adding form.
		$val =~ s/F|f/$lex{Form} /;
	    }
	    $displaygrade = $val;
	}
	print qq{<input type="checkbox" name="G:$gr" value="1">$displaygrade };
    }
    print qq{</td></tr>\n};

   
    print qq{<tr><td class="bra">$lex{OR}</td><td></td></tr>\n};
    
    # Homeroom
    print qq{<tr><td class="bra">$lex{Select} $lex{Homeroom}</td>};
    print qq{<td class="la">\n}; 
    foreach my $hr ( sort {$a <=> $b} @homerooms ) {
	print qq{<input type="checkbox" name="H:$hr" value="1">$hr };
    }
    print qq{</td></tr>\n};

    print qq{<tr><td colspan="2" style="border-bottom:1px solid gray"></td></tr>\n};

    # Select which emails
    print qq{<tr><td class="bra">$lex{Select}</td><td class="la">\n};
    print qq{<input type="checkbox" name="selStudent" value="1"> };
    print qq{$lex{Student} $lex{Email}<br>\n};

    print qq{<input type="checkbox" name="selPar1" value="1"> };
    print qq{ $lex{Parent} 1 $lex{Email}<br>\n};

    print qq{<input type="checkbox" name="selPar2" value="1"> };
    print qq{ $lex{Parent} 2 $lex{Email}</td></tr>\n};

    print qq{<tr><td colspan="2" style="border-bottom:1px solid gray"></td></tr>\n};
    
    # Check next page?
    print qq{<tr><td class="bra">$lex{'Next Page'} $lex{Checked}?</td><td class="la">\n};
    print qq{<input type="checkbox" name="checked" value="checked"></td></tr>\n};

    # Continue
    print qq{<tr><td></td><td class="la">};
    print qq{<input type="submit" value="$lex{Continue}">};
    print qq{</td></tr>\n};

    print qq{</table></form>\n};
    print qq{</body></html>\n};

    exit;

}



#-------------------
sub selectRecipients { # Choose students/parents to email to and put in message
#-------------------

    # foreach my $key (keys %arr) { print qq{K:$key V:$arr{$key}<br>\n}; }
    # passed 3 email selects, check, and then all groups G: or H:
    
    my $selStudent = $arr{selStudent};
    delete $arr{sel};

    my $selPar1 = $arr{selPar1};
    delete $arr{selPar1};

    my $selPar2 = $arr{selPar2};
    delete $arr{selPar2};

    # $checked is already defined at top, if selected in startpage.
    # only groups left in %arr now.

    my (%sort, %student);
    foreach my $key ( keys %arr ) {
	my ($group, $val) = split(':', $key);

	my $sth;
	if ( $group eq 'G' ) {
	    $sth = $dbh->prepare("select lastname, firstname, studnum, grade, homeroom, 
               email, par1_email, par2_email from student where grade = ?");
	    $sth->execute( $val );
	    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
	} else { # homeroom
	    $sth = $dbh->prepare("select lastname, firstname, studnum, grade, homeroom,
               email, par1_email, par2_email from student where homeroom = ?");
	    $sth->execute( $val );
	    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
	}

	# Loop through the students
	while ( my $ref = $sth->fetchrow_hashref ) {
	    my %r = %$ref;
	    $sort{"$r{lastname}$r{firstname}$r{studnum}"} = $r{studnum};
	    $student{$r{studnum}} = $ref;
	}
    }

    

    # Setup the form and start of table.
    print qq{<form action="$self" method="post" enctype="multipart/form-data">\n};
    print qq{<input type="hidden" name="page" value="2">\n};

    # Start table.
    print qq{<table cellpadding="3" border="0" cellspacing="0" style="float:left;margin:0 1em;">\n};

    # Entry Values
    print qq{<tr><td class="bla">$lex{Subject} <input type="text" name="subject" style="width:30em;">};
    print qq{</td></tr>\n};

    print qq{<tr><td class="bla">$lex{Message} Format <select name="messageformat">};
    print qq{<option value="html">HTML</option><option value="text">Text</option></select></td></tr>\n};
    
    print qq{<tr><td class="bla">$lex{Message}<br><textarea name="message" rows="10" cols="60">};
    print qq{</textarea></td></tr>\n};

    print qq{<tr><td class="bla">$lex{'Attach File'} <input type="file" name="filename"></td></tr>\n};

    print qq{</table>\n};

    
    # New Floated Table.
    print qq{<table cellpadding="3" border="1" cellspacing="0" style="float:left;">\n};
#    print qq{<tr><th>$lex{Student}</th><th>$lex{Student}<br>$lex{Email}</th>\n};
#    print qq{<th>$lex{Parent} 1<br>$lex{Email}</th><th>$lex{Parent} 2<br>$lex{Email}</th></tr>\n};

    
    my $first = 1;
    foreach my $key ( sort keys %sort ) {
	my $studnum = $sort{$key};
	my %r = %{$student{$studnum}};
	
	if ( $first ) {
	    print qq{<tr><th>$lex{Student}</th><th>Gr/Frm/HR</th><th>$lex{Student}<br>$lex{Email}</th>\n};
	    print qq{<th>$lex{Parent} 1<br>$lex{Email}</th><th>$lex{Parent} 2<br>$lex{Email}};
	    print qq{</th></tr>\n};

	    print qq{<tr><td class="cn" colspan="5"><input type="submit" value="$lex{Continue}"></td></tr>\n};
	    $first = 0;
	}

	print qq{<tr><td class="la"><b>$r{lastname}</b>, $r{firstname} ($r{studnum})</td>\n};

	# Grade / Form / Homeroom
	my $gr = $r{grade};
	if ( $schoolmode == 1 ) {
	    my $val = $g_FormMap{$gr};
	    if ( not $val ) { $val = $gr; }
	    if ( $val =~ m/F|f/ ) { # we are adding form.
		$val =~ s/F|f/Frm/;
	    }
	    $gr = $val;
	}
	print qq{<td>$gr};
	if ( $r{homeroom} ) { print qq{,$r{homeroom}}; }
	print qq{</td>};
	

	print qq{<td>};
	if ( $r{email} and $selStudent ) {
	    print qq{ <input type="checkbox" name="$studnum:S:$r{email}" value="1" $checked> $r{email}};
	}
	
	print qq{</td><td>};
	
	if ( $r{par1_email} and $selPar1 ) {
	    print qq{ <input type="checkbox" name="$studnum:P1:$r{par1_email}" value="1" $checked>};
	    print qq{$r{par1_email}};
	}
	
	print qq{</td><td>};
	
	if ( $r{par2_email} and $selPar2 ) {
	    print qq{<input type="checkbox" name="$studnum:P2:$r{par2_email}" value="1" $checked>};
	    print qq{$r{par2_email}};
	}
	print qq{</td></tr>\n};
    }

    # Print Submit Row
    print qq{<tr><td colspan="5" class="cn">};
    print qq{<input type="submit" value="$lex{'Continue'}"></td></tr>\n};
    
    print qq{</table>\n</form></body></html>\n};
    
    exit;

}



#------------
sub postEmail  {
#------------

    # foreach my $key ( sort keys %arr ) { print "K:$key V:$arr{$key}<br>\n"; }
    # Passed: subject, message, messageformat, filename and then all email addresses

    use Email::Sender;  # email library
    use Email::Stuffer;
#    use Email::Sender::Transport::SMTP::Persistent;
    use Email::Sender::Transport::SMTP;
    
    
    my $subject = $arr{subject};
    delete $arr{subject};

    my $message = $arr{message};
    delete $arr{message};

    my $messageformat = $arr{messageformat}; # text or html.
    delete $arr{messageformat};

    
    # Create Transport object
    my $transport;
    if ( $g_EmailUseTLS ) {
#	$transport = Email::Sender::Transport::SMTP::Persistent->new({
	$transport = Email::Sender::Transport::SMTP->new({
	    host => $g_EmailServer,
	    port => $g_EmailPort,
	    ssl  => 'starttls',
	    sasl_username => $g_EmailAuthId,
	    sasl_password => $g_EmailAuthPwd
									});
    } else { # normal SMTP transport
#	$transport = Email::Sender::Transport::SMTP::Persistent->new({
	$transport = Email::Sender::Transport::SMTP->new({
	    host => $g_EmailServer,
	    port => $g_EmailPort,
								     });
    }    
    
   
    # Create Email object, and set some values.
    my $email = Email::Stuffer
	    ->from( $g_EmailNoReply)
	    ->subject( $subject )
	    ->html_body( $message )
	    ->transport( $transport )
	    ;

   
    # Set the Message (in a format)
    if ( $messageformat eq 'html' ) {
	$email->html_body($message);
    } else {
	$email->text_body($message);
    }
    

    # now deal with file, if any
   
    my $file = $q->param("filename");
    my $filename = $file;  # fileName is output filename, file is input.
    delete $arr{filename}; # value not needed.

    my ($name, $ext); 

    if ( $filename ) {   # it will not have leading path info...

	$filename =~ s!^.*(\\|\/)!!; 
	$filename = lc($filename);
	@name = split(/\./, $filename); # split on dots.
	$ext = $name[$#name];  # last element is the extension.
    
	open ( OUTFILE, ">$filename") || 
	    die $lex{'Cannot open file'}. " $filename"; 
	my $bufcount = 0;
	while ( my $bytesread = read( $file, my $buffer, 1024) ) { 
	    print OUTFILE $buffer;
	    $bufcount++;
	    if ( $bufcount > $maxbufcount ) {
		print qq{<h1>$lex{'Maximum File Upload size exceeded!'}};
		print qq{ ($maxbufcount K)</h1>\n};
		print qq{</body></html>\n};
		die $lex{'Maximum File Upload size exceeded!'};
	    }
	}

	close OUTFILE;

	# We should now have the file in place.
	# my @cmd = split / /, "mv $filename $downloaddir";
	# system( @cmd );

	# attach to email
	$email->attach_file($filename);
	
    } # end of File upload.


    my (%duplicates, @addresses);

    my $sth = $dbh->prepare("select lastname, firstname from student where studnum = ?");
    
    foreach my $key ( sort keys %arr) {
	my ($studnum, $field, $emailaddress) = split(':', $key);

	$sth->execute($studnum);
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my ($lastname, $firstname) = $sth->fetchrow;
	
	if ( $duplicates{$emailaddress} ) { next; } # skip existing email addresses.
	$duplicates{$emailaddress} = 1;

	push @addresses, $emailaddress;

	# set the address;
	$email->to( $emailaddress );
	
	# send the message
	my $result = $email->send();
	if ( not $result ) { # failure
	    print qq{<div style="color:red;font-weight:bold;">Failure for $firstname $lastname ($studnum) - $field - $emailaddress</div>\n};
	} else { # success
	    print qq{<div style=">Email sent for $firstname $lastname ($studnum) - $field - $emailaddress</div>\n};
	}
    }

#    $transport->disconnect;  # disconnect persistent SMTP connection.
    
    if ( $filename ) {
	unlink $filename or warn "Could not unlink $filename: $!";
    }


    print qq{<h1>$lex{'Email Complete'}</h1>\n};

    print qq{<p>[ <a href="$homepage">$lex{Main}</a> ]</p>\n};
    print qq{</body></html>\n};


    exit;

} # End of postEmail

