#!/usr/bin/perl -w

# report_grades.pl, by Reid Priedhorsky for CSCI 2021
#
# This program helps to record grades and send feedback to students.
#
# In each subdirectory of the current working directory, this program looks
# for files named FEEDBACK.txt and README.txt. It lists the grade from
# FEEDBACK.txt, then (optionally, if subject and cc address are provided)
# mails a copy of FEEDBACK.txt to each email address found in README.txt.
#
# Usage examples:
#
#   (to just print out grades)
#   $ cd lab2
#   $ ../report_grades.pl
#
#   (to send the contents of FEEDBACK.txt to the appropriate students)
#   $ cd lab2
#   $ ../report_grades.pl "CSCI 1902- Feedback on Lab 2" reid@umn.edu
#
# You should probably try the former mode first, to make sure everything looks
# good, before mailing students. This program will abort if there is a
# problem, so you don't want to mail half the students and then run into a
# problem -- you'll end up mailing the first half of the students again when
# you fix it...

use strict;
use warnings;

my $EMAIL_RE = '[\w.-]+@[\w.-]+\.[\w.-]+';  # matches email addresses

my ($subject, $cc);

if (@ARGV == 0) {
  $subject = undef;
  print "\nNo emails will be sent.\n\n";
} elsif (@ARGV == 2 and not $ARGV[0] =~ /^-/) {
  $subject = $ARGV[0];
  $cc = $ARGV[1];
  print "\nEmail subject will be \"$subject\".\n";
  print "Emails will be cc'ed to \"$cc\".\n\n";
} else {
  print STDERR "\nUsage: $0 [EMAIL_SUBJECT CC_ADDRESS]\n";
  print STDERR "See source for more info.\n\n";
  exit(1);
}

if (defined $subject) {
  print "Is this OK? (y/n) ";
  if (not <STDIN> =~ /^y/i) {
    print "Aborting.\n";
    exit(0);
  }
}

foreach my $dir (glob('[a-z]*')) {
  my ($grade, @emails);
  $grade = get_grade($dir);
  @emails = get_emails($dir);
  if (@emails == 0) {
    print "$dir : $grade\n";
  } else {
    if (defined $subject) {
      # send mail
      system("mail -s '$subject' -c '$cc' " . join(",", @emails)
             . " < $dir/FEEDBACK.txt");
    }
    foreach my $email (@emails) {
      print "$dir : $email : $grade\n";
      $dir =~ s/./ /g;
    }
  }
}

sub get_grade {
  my $grade = `grep -i '^[ ]*total' $_[0]/FEEDBACK.txt`;
  $grade =~ s/^[ ]*total[ .:]*//i;
  $grade =~ s/\n*$//;
  if ($grade eq '') {
    print STDERR "No total in $_[0]/FEEDBACK.txt??? Aborting.\n";
    exit(1);
  }
  return $grade;
}

sub get_emails {
  my ($text);
  local $/ = undef;
  open(FP, "< $_[0]/README.txt") or return ();
  $text = <FP>;
  return ($text =~ /$EMAIL_RE/g);
}
