#!/usr/local/bin/perl5
# batchcode: sort output results and generate simple statistics
# Copyright (C) 1998-2001  Carnegie Mellon University
#
# This program 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

use strict;

# hash to record the order that we want to sort results
my (%status) = ( Catastrophic => 1,
		 Restart => 2,
		 Abort => 3,
		 Pass => 4,
		 );

# function to yank the status out of a string
sub status {
    return ( ($_[0] =~ m/Done - (\w+)/s)[0] );
}

# function to compare two strings with statuses imbeded in them
sub comp1 {
    return $status{status($a)} <=> $status{status($b)};
}

# function to compare two status strings
sub comp2 {
    return $status{$a} <=> $status{$b};
}

#############################################
#
# main line starts here
#
#############################################

# set the input record seperator to make reading records easier
$/ = "----\n";

my %global_results;     # hash to count each type of result
my $global_total;       # total number of tests run;

# process each input file
foreach my $input (@ARGV) {
    my @tests;       # array of all the test results
    my %results;     # hash to count each type of result
    my $total;       # total number of tests run;

    my $new_status;  # temporary variables to determine where to 
    my $old_status;  #  put seperators between types of results
    
    # Create path for Ballista output file from function name
    my $dir_name = $input;
    if ($dir_name =~ /.*\-\>.*/) {
	$dir_name =~ s/\-\>/\./;
    }
    print "dir name = $dir_name\n";

    my $input_file = "test_defs/$dir_name/$input" . ".out";

    # open the current input file
    open(INPUT, $input_file) || die "Can't open input file $input_file: $!";
    
    # read in each record
  RECORD:
    while(<INPUT>) {
	# chop off any information about talking to the server
	#s/^.*Got the data\n//s;
	# skip the record if it's empty
	next RECORD unless length $_;

	# store the record on the stack
	push @tests, $_;
    }

    # sort the records based on the order in %status
    @tests = sort comp1 @tests;

    # get a count of the number of tests run
    #$total = @tests;
    #$global_total += $total;

    #my @func_name_array = split(/\//, $input);

    # input variable is the function name
    my $function_name = $input;

    #$function_name =~ s/\..*//;
    #print "function = $function_name \n";

    # Copy dataTypes file for this function from its directory
    system("cp test_defs/$dir_name/dataTypes .");

#    system("cp test_defs/$function_name/userLibs .");
#    system("cp test_defs/$function_name/osLibs .");

    print "Generating code for $function_name ...";
    # print out the newly sorted list
    foreach (@tests) {

	# put seperators between different types of results
	$new_status = status($_);

#	unless ($new_status eq $old_status) {
#	    print '=' x 75, "\n";
#	}
	$old_status = $new_status;

	# count each individual type of result
	$results{$new_status}++;
	$global_results{$new_status}++;

	# Create code for all failures but not for passes
	if ($new_status ne "Pass") {
	    my @strings;

	    #split record by lines
	    @strings = split(/\n+/, $_);

	    my $i;
	    my $j;
	    #for ($i = 0; $i < @strings; $i++) {
		#print "@strings[$i] \n";
	    #}	    
	    #print "\n";
	    
	    my @temparray;
	    my @types;
	    my @testcase;
	    my $count = 0;

	    for ($i = 0; $i < @strings; $i++) {
		# last if @strings[$i] =~ /.*rval:.*/;
		last if @strings[$i] =~ /Done/;

		# Each line before "rval" contains a Ballista datatype
		# and specific test case parameter
		# Split off each and format them for the create_code.pl script

		if (@strings[$i] =~ /\S./) {
		    @temparray = split(/\s+/, @strings[$i]);
		    @types[$count] = shift(@temparray);
		    print "type = @types[$count] \n";
		    
		    @testcase[$count] = "";
		    for ($j = 0; $j < @temparray; $j++) {
			@temparray[$j] =~ s/.*@types[$count]_//;
			@testcase[$count] .= @temparray[$j] . "lNw";
		    }
		    print "testcase = @testcase[$count] \n";
		    $count++;
		}
	    }
	    
	    #print "@types |\n @testcase |\n";
	    #print "$new_status \n";
	    #print "\n";
	    
	    # print the current record
	    # print;

	    my $numparams = @types;
	    my $commandline;

	    # Create command line string for executing create_code.pl
	    $commandline = "create_code.pl $function_name $new_status "; 
	    $commandline .= "$numparams ";

	    my $filename = "test_defs/$dir_name/$dir_name";

	    for ($i = 0; $i < $numparams; $i++) {
		$commandline .= "@types[$i] @testcase[$i] ";
		$filename .= "_@testcase[$i]";
	    }

	    $filename .= ".cpp";
	    $commandline =~ s/\>/\\\>/g;
	    $filename =~ s/\>/\\\>/g;
	    print "$commandline > $filename\n\n";
	    system("$commandline > $filename");
	}
    }
    print "done\n";
    
#    # print a seperator so we can easily find the summary info 
#    print '*' x 75, "\n";
#    print "file: $input\n\n";

#    # print statistics for each type of result
#    foreach (sort comp2 keys %results) {
#	# the count of this type of result
#	print "$results{$_}\t";
#	# te percentage
#	printf ("%3i%%\t", int ($results{$_} / $total * 100 ));
#	# the type of result
#	print "$_\n";
#    }

#    # print the total number of tests for this file
#    print "--\n$total\t100%\ttotal tests\n";
    
#    # print another seperator, so we can seperate it from the next file
#    print '*' x 75, "\n";
}

## print global statistics for each type of result
#print '*' x 75, "\n";
#print "Global statistics\n\n";

#foreach (sort comp2 keys %global_results) {
#    # the count of this type of result
#    print "$global_results{$_}\t";
#    # te percentage
#    printf ("%3i%%\t", int ($global_results{$_} / $global_total * 100 ));
#    # the type of result
#    print "$_\n";
#}

## print the total number of global tests for this file
#print "--\n$global_total\t100%\ttotal tests\n";
