#!/usr/bin/perl -w
# description: see Usage at bottom

use strict;
use vars qw($opt_d $opt_h $opt_n);
use SafeSysCall;
## use Data::Dumper;

my $myName = $0;
$myName =~ s|^.*/([^/]+)$|$1|; # get basename of current program

use Getopt::Std;
&getopts('d:hn');
if ($opt_h) { # i.e. help
    &showUsage;
}
my $debug;
$debug = 0 unless ($debug = $opt_d);
my $nop;
$nop = 0 unless ($nop = $opt_n);
if($nop){
$debug = 1 unless($debug);
}

my $numArgs = 0;  # number of required arguments; 
if($#ARGV != $numArgs ) { 
    $numArgs++;
# if there aren't the right number of arguments on the command line
    warn "$myName: wrong number of arguments on command line, 
There should be $numArgs.\n";
    &showUsage;
}

# main

my @partDirs = ();
my @scoreCmds = ();
my @filePats = ();

my $otherPat = ".xml";
my $gsDir = "/n/turtle/db/SemEval/gs";


my $infile = $ARGV[0];  # one required input file
open(INFILE, $infile) || die
    "$myName: can't open input file \"$infile\"; dying.\n";
my (@lines) = <INFILE>;
close(INFILE);

my $line = "Dummy";
my $vals = "Dummy2";
my $logFile = "";



for $line(@lines) { # initialization loop
  next if ($line =~ /^\s*$/); # skip blank lines
  next if ($line =~ /^#/); # skip comments
  if ($line =~ /^participants:\s*(.*$)/) {
    $vals = $1;
    chomp($vals);
    @partDirs = split(/,\s*/, $vals);
}
  elsif ($line =~ /^scoring:\s*(.*)$/) {
    $vals = $1;
    chomp($vals);
    @scoreCmds = split(/,\s*/, $vals);
}
elsif ($line =~ /^logfile:\s*(.*)$/) {
  $logFile = $1;
  chomp($logFile);
}
elsif ($line =~ /^filePatterns:\s*(.*)$/) {
  $vals = $1;
  chomp($vals);
  @filePats = split(/,\s*/, $vals);
}
  else {
    warn 
"$myName: unrecognized line in parameter file \"$infile\"; skipping.\n",
$line;
  }
}  
 
 # end initialization loop

$logFile = "-" unless($logFile); # write to STDOUT unless user supplies

open(LOGFILE, ">$logFile") || die
    "$myName: can't open log file \"$logFile\" for writing; dying.\n";

  if ($debug ==1) {
    print  LOGFILE "Debug:\nlogFile: ", $logFile, "\nPartDirs :", @partDirs, "\nscoreCmds:", @scoreCmds, "\nfilePats:", @filePats, "\n";
  }

my $scoreCmd = "DummyCmd";
# my $filePat = "DummyFilePat";
my $partDir = "DummyPartDir";
my $file = "DummyFile";
my @cmdList = ();


while ($scoreCmd = shift(@scoreCmds)) {
    foreach $partDir (@partDirs) {
	print LOGFILE "Debug @ 2a: partDir = $partDir\n" if($debug==2);
	opendir(PDIR, $partDir) || die 
	    "$myName: can't read directory \"$partDir\"; skipping.";
	while(defined($file = readdir(PDIR))) {
	    next unless $file =~ /\.xml$/; # skip non-xml files
	    print LOGFILE "Debug @ 2b: file = $file\n" if ($debug==2);
	    if($scoreCmd =~ /-l/) {
		next if $file =~ /_sem\.xml$/; # we want only plain xml
	    }
	    else {# we want only semantic dependency xml
		next unless $file =~ /_sem\.xml$/; 
	    }
	    if (@filePats) {
		foreach my $filePat (@filePats) {
		    print LOGFILE "Debug @ 2d: filePat = \"$filePat\"\n" if($debug==2);
		    if ($file =~ /$filePat/i) {
			&runOrList($partDir,$file);
			print LOGFILE "Debug @ 2e: file \"$file\" matches, pushed\n" if ($debug==2);
		    }
		    else {
			print LOGFILE "Debug @ 2e: file \"$file\" failed match\n" if ($debug==2);
		    }
		}
	    }
	    else {
		&runOrList($partDir,$file);
		print LOGFILE "Debug @ 2f: no filePat; \"$file\" pushed\n" if ($debug==2);
	    }
	}
    }
}
    

if($debug == 1) {
    if(@cmdList) {
	print LOGFILE "debugging @ 2: Command list:\n";
	for $file (@cmdList) {
	    print LOGFILE "$file\n";
	}
    }
    else {
	print LOGFILE "debugging @ 2: Command list is empty\n";
    }
}


sub runOrList {

    my ($testDir, $fileName) = @_;
    my $cmdLine;
    my $timeString;

      $cmdLine = "$scoreCmd $gsDir/frames.xml $gsDir/frRelation.xml $gsDir/$fileName $testDir/$fileName >> $logFile";
    if ($nop) {
	push(@cmdList, $cmdLine);
    }
    else {
      my $timeString = localtime;
      warn "$myName: running \"$scoreCmd on $testDir/$fileName\" at $timeString\n";
      safeSysCall($cmdLine);
    }
}

close LOGFILE;
warn "$myName: exited normally.";


sub showUsage {
	die 
"\nUsage: $myName <params_file>

Runs one or more scoring programs on one or more submitted data files,
comparing them to the gold standard file(s). Takes one argument which
is the path to a parameters file.

The parameters file must contain two lines; one is of the form

participants: <participant_dir>+

where participant_dir is a comma-separated list of subdirectory names
under the current directory which directly contain submitted data
files. The other required line is of the form

scoring: (<scorer name> [scorer opts])+

which gives a comma-separated list of the scoring programs on the
current path. Command-line options on the scoring programs can be
included in the list (separated from the program name by one or more
spaces); program names can be repeated with different options.

The parameter file may optionally include the following lines:

logfile: <log_file_name>

which saves all output in a log file. If this is omitted, all output
is written to STDOUT.

File selection:

If the parameter file includes a line of the form

filePatterns: <pattern>+

the program finds all files in the participant directory(s) that match
these patterns and runs the selected scorers against the approprate
matching file(s). File name matching is not case sensitive.

If this line is ommitted, the selected scorers are run against all
appropriate files in the directory; at the moment, for labels-only
scoring, this means <name>.xml, and for semantic dependency scoring,
<name>_sem.xml (meaning the output of fttosem.pl).

\n";
}
