#!/usr/bin/perl

if ($#ARGV < 2 || $#ARGV > 3) {
    print STDERR "Usage: runtests PLATFORM COM-PORT-FOR-APP COM-PORT-FOR-TOSBASE [test-regexp]\n";
    exit 2;
}

$platform = $ARGV[0];
$comapp = $ARGV[1];
$combase = $ARGV[2];

$tests = ".*";
$tests = $ARGV[3] if $#ARGV == 3;

$dontconnect = 1;
do "./tools.pm";

$ENV{PLATFORM} = $platform;
$ENV{MOTECOM} = "sf\@localhost:$APP_PORT";
$ENV{MOTEBASE} = "sf\@localhost:$BASE_PORT";

# start serial forwarders

$pidapp = sf_start($APP_PORT, "serial\@$comapp:$platform");
$pidbase = sf_start($BASE_PORT, "serial\@$combase:$platform");

system("/bin/rm -rf output");
die "Can't create output directory" unless mkdir("output");

sf_wait("localhost", $APP_PORT);
sf_wait("localhost", $BASE_PORT);

# The first packet sent sometimes has problems. Send something hopefully harmless
r_connect(APP, BASE);
send_base(message(65534, 254, 0));
send_app(message(65534, 254, 0));
r_close;

@failed = ();
while (<*>) {
    if (!/^(output|CVS)$/ && -d $_ && /$tests/) {
	runtests($_);
    }
}

if ($#failed >= 0) {
    print "THE FOLLOWING TESTS FAILED for $platform:\n";
    print join("\n", @failed);
    print "\n";
}
else {
    print "All tests PASSED\n";
}

END { kill 9, $pidapp; kill 9, $pidbase; }

sub runtests {
    my ($test) = @_;

    die "Can't create output directory for $test" unless mkdir("output/$test");

    die "Can't enter test directory $test" unless chdir($test);

    if (runsingletest($test, "app")) {
	while (<*.tst>) {
	    system("./reset") || die "./reset doesn't work";
	    sleep 1;
	    runsingletest($test, $_);
	}
    }

    die ".. missing" unless chdir("..");
}

sub runsingletest {
    my ($test, $subtest) = @_;

    print "running $test:$subtest\n";
    $exitcode = system("./$subtest >../output/$test/$subtest 2>&1");

    if (($exitcode & 0xff) == 0) {
	$exitcode >>= 8;
    }
    else {
	$exitcode = 2;
    }

    if ($exitcode == 1) {
	$status = "SKIP";
    }
    elsif ($exitcode == 0) {
	$status = "PASS";
    }
    else {
	$status = "FAIL";
	push @failed, "$test:$subtest";
    }

    print "  $status\n";

    return $exitcode == 0;
}
