#!/usr/bin/perl
use strict;
use warnings;

my %test = ('binary_incr' => { '0' => '1', '0011001' => '0011010' },
	    'hello_world' => { '' => 'hel1o_world' },
	    'stack' => { '1111P1PA' => '11111' },
	    'binary_add' => { '0_0' => '0', '0_1' => '1', '10_11' => '101' },
	    'echo' => { '0' => '0', 'hello_world' => 'hello_world', '___' => '' },
	    'multiply' => { '1111_11111' => '1111_11111_1111111111111' },
	    'parens' => { '3' => 'xoxoxo_xxooxo_xoxxoo_xxoxoo_xxxooo' },
	    '0' => { '0' => '1', '0011001' => '0011010' },
	    'nostate1' => { '0' => '0'},
	    'nostate2' => { '' => '1' },
	   );

my %badtests = ('bad1' => { '0' => '0' },
	       'bad2' => { '0' => '0' },
	       'bad3' => { '0' => '0' },
	       'bad4' => { '0' => '0' },
	       'bad5' => { '0' => '0' },
	       'bad6' => { '0' => '0' },
	       'bad7' => { '0' => '0' },
	       'empty' => { 'x' => 'x', '' => ''},
	      );

my %undefinedtests = ('dup' => { '00010' => '00011', '11110' => '11111', '0' => '1', '1' => '10', '0011001' => '0011010' });

my %lang = ('pl' => 'perl', 'py' => 'python', 'rb' => 'ruby');

die "Usage: $0 directory" unless @ARGV == 1;
my $dir = shift;
opendir(DIR, $dir) or die "couldn't open dir: $!";

for my $file (readdir(DIR)) {
  my ($ext) = ($file =~ /\.([^.]+)$/);
  next unless defined $ext and exists $lang{$ext};
  print "Testing $file...\n";
  for my $tm (sort keys %test) {
    my $io = $test{$tm};
    next if ($tm eq 'empty') and $file eq 'sanderson.pl';
    next if ($tm eq 'binary_add' or $tm eq 'parens') and $file eq 'fuglerud.pl';
    while (my ($input, $expected_output) = each %$io) {
      my $output;
      eval { $output = `$lang{$ext} $dir/$file $dir/${tm}.tm $input 2>&1` };
      if ($@) {
	print "$file died on $tm $input: $@\n";
      } else {
	chomp $output;
	if ($output eq $expected_output) {
	  print "$file succeeded on $tm $input\n";
	} else {
	  print "$file failed on $tm $input. Expected '$expected_output'; received: $output\n";
	}
      }
    }
  }
  for my $tm (sort keys %badtests) {
    my $output;
    my $died = system("$lang{$ext} $dir/$file $dir/${tm}.tm");
    print "$file " . ($died ? "died" : "didn't die. Received: $output") . " on $tm\n";
  }
}
