#!/usr/local/bin/perl -w

###
# This script is used to handin files for assignments
# It does the following:
#
# 1. Finds the current user's partner from the
#    main source file
#
# 2. Checks that the current user can read from
#    the partner's directory.  If not, the user
#    gets an error message, with what he should do
#
# 3. Finds the largest version of the assignment
#    currently handed in.
#
# 4. Copies the new version from the user's directory
#    along with its version number in the filename
#
#
# HOW TO USE THIS SCRIPT
# ======================
#
# To use this script for the collection of files
# for an assignment, you must create a file
# called "handin_files" for each assignment to be
# collected.  handin_files has the following
# format:
#
#   - Each line can be either a comment or
#     a file glob pattern (or a blank line)
#   - Comments begin with a '#' symbol
#   - The first 'file glob' *MUST* be a unique
#     file name, and can not be a file glob pattern
#     This file is used to parse out the userid
#     of the current user's partner

use strict;
use File::Copy;

###
# Authenticate the user to the CS Realm
`afslog CS.CMU.EDU`;

###
# Make sure there's an assignment specified
die ("No assignment specified.  Usage: handin <L1 | H1 | L2 ...>") if($#ARGV < 0);

my $CLASS_HOME = "/afs/cs/academic/class/15213-s03";
my $ASSN_HOME = "$CLASS_HOME/labs/$ARGV[0]";
my $HANDIN_HOME = "$CLASS_HOME/handin";
my $USER_ASSN = "$ENV{'HOME'}/213hw/$ARGV[0]";
my $CUR_USER = $ENV{'USER'};
my $USER_HANDIN = "$HANDIN_HOME/$CUR_USER";
my $USER_ASSN_HANDIN = "$USER_HANDIN/$ARGV[0]";
my $LAST_VERSION = 0;
my $PARTNER = "";
my $temp = 0;
my $user1 = "";
my $user2 = "";
my ($PARTNER_HANDIN, $PARTNER_ASSN_HANDIN, $file_contents, $file, $temp2, @files, @glob_files);

###
# Adjust for stupid home directory on the FISH cluster
if($ENV{'HOME'} =~ /(.*\/$ENV{'USER'})\/15-213/) {
  $USER_ASSN = "$1/213hw/$ARGV[0]";
}

###
# Get the information about the assignment being handed in
# and find all the files that we are interested in copying
die ("That assignment doesn't exist") if(!(-e "$ASSN_HOME"));
die ("You do not have a directory named '$USER_ASSN'.  This is where your assignment must be stored to handin") if(!(-e "$USER_ASSN"));

open FILE, "< $ASSN_HOME/handin_files" or die ("Could not retrieve $ASSN_HOME/handin_files");
while(<FILE>) {
  chomp;
  next if($_ eq "");
  if($_ !~ /#.*/) {
    if($temp == 0) {
      push @files, ($_);
      $temp = 1;
    } else {
      push @files, (glob "$USER_ASSN/$_");
    }
  }
}
close FILE;

for($temp = 0; $temp <= $#files; ++$temp) {
  if($files[$temp] =~ /$USER_ASSN\/(.*)/) {
    $files[$temp] = $1;
  }
}

die ("None of the files specified were matched.") if($#files < 0);
if(!(-e "$USER_ASSN/$files[0]")) {
  print "$USER_ASSN/$files[0]\n";
  die ("You are missing the main source file $USER_ASSN/$files[0],\nwhich is required to handin this assignment");
}

###
# Find the user's partner (I *hope* this works correctly for everyone)
# Note that the first file in @files is the 'main' source file
open FILE, "< $USER_ASSN/$files[0]" or die ("Could not open $USER_ASSN/$files[0]");
$file_contents = "";
while(<FILE>) {
  $file_contents .= $_;
}
close FILE;

$temp = index $file_contents, "{", (index $file_contents, "team_struct");
$temp2 = substr $file_contents, $temp + 1, ((index $file_contents, "}", $temp) - $temp - 1);

my @struct_lines = split /\n/, $temp2;
$temp = 0;
foreach $temp2 (@struct_lines) {
  chomp $temp2;
  if($temp2 =~ /\"(.*)\"(,|;)?/) {
    ++$temp;
    if($temp == 2) {
      $user1 = $1;
      if($user1 =~ /(.*)\@.*/) {
        $user1 = $1;
      }
    } elsif($temp == 4) {
      $user2 = $1;
      if($user2 =~ /(.*)\@.*/) {
        $user2 = $1;
      }
    }
  }
}

if(($ARGV[0] =~ /H.*/) && ($temp != 2)) {
  print "This seems to be a homework assignment.  However, you have not\n";
  print "specified the correct user information.  Please make sure that\n";
  print "the team structure in your $files[0] looks exactly like this:\n\n";
  print "  team_struct team =\n";
  print "  {\n";
  print "    \"Name\",\n";
  print "    \"Andrew ID\"\n";
  print "  };\n";
  die();
} elsif(($ARGV[0] =~ /L.*/) && ($temp < 4)) {
  print "I can't parse your team information from $files[0].\n";
  print "Making sure that your team structure is in this file\nand looks exactly like this will help:\n\n";
  print "  team_struct team =\n";
  print "  {\n";
  print "    \"Name\",\n";
  print "    \"AndrewID\",\n";
  print "    \"Partner\",\n";
  print "    \"Partner's Andrew ID\"\n";
  print "  };\n";
  die();
}

die ("Neither of the team members ($user1, $user2) in the file $files[0] is you!") if(($user1 ne $CUR_USER) && ($user2 ne $CUR_USER));

if($user1 eq $CUR_USER) {
  $PARTNER = $user2;
} else {
  $PARTNER = $user1;
}

$PARTNER_HANDIN = "$HANDIN_HOME/$PARTNER";
$PARTNER_ASSN_HANDIN = "$PARTNER_HANDIN/$ARGV[0]";

###
# Make sure the proper directories exist for this user

# User's handin directory
if(!(-e "$USER_HANDIN")) {
  print "Your handin directory does not exist.  Either you are not a\n";
  print "student in this course, or have yet to run the checkin script.\n";
  print "If you think this is wrong, e-mail a course instructor.\n";
  die ();
}

# Assignment handin directory
if(!(-e "$USER_ASSN_HANDIN")) {
  printf "Creating your $ARGV[0] handin directory...\n";
  mkdir "$USER_ASSN_HANDIN", 0755;
  if(!(-e "$USER_ASSN_HANDIN")) {
    print "I couldn't create your $ARGV[0] handin directory.\n";
    die ("Please try and create the directory yourself:\n$USER_ASSN_HANDIN");
  }
}

###
# Find the latest version of the assignment from
# the group's directories by globbing the current
# user's directory, and then the partner's directory

# User's directory
@glob_files = glob "$USER_ASSN_HANDIN/*";
foreach $file (@glob_files) {
  if($file =~ /.*\.v(\d+)/ && $1 > $LAST_VERSION) {
    $LAST_VERSION = $1;
  }
}

# Partner's directory, if there's a partner
@glob_files = ();
if($PARTNER ne "" && (-e $PARTNER_ASSN_HANDIN)) {
  @glob_files = glob "$PARTNER_ASSN_HANDIN/*";
  foreach $file (@glob_files) {
    if($file =~ /.*\.v(\d+)/ && $1 > $LAST_VERSION) {
      $LAST_VERSION = $1;
    }
  }
}

###
# Copy over each file to the user's handin directory
# with the new version number.
++$LAST_VERSION;
print "Handing in $ARGV[0] version $LAST_VERSION:\n\n";
foreach $file (@files) {
  print "$file.v$LAST_VERSION\n";
  die("Couldn't find $file in your directory.") if(!(-e "$USER_ASSN/$file"));
  copy "$USER_ASSN/$file", "$USER_ASSN_HANDIN/$file.v$LAST_VERSION";
  die ("There was a problem copying files to your handin directory.\nI was looking for $file.v$LAST_VERSION.") if(!(-e "$USER_ASSN_HANDIN/$file.v$LAST_VERSION"));
}

print "\nSuccessful!\n\n";
