#!/usr/bin/perl
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl test.pl'

######################### We start with some black magic to print on failure.

# Change 1..1 below to 1..last_test_to_print .
# (It may become useful if the test is moved to ./t subdirectory.)

use strict;
use lib '.';
BEGIN { $| = 1; print "1\n"; }
use test; # configuration created by Makefile.PL
use vars qw($loaded);
END {print "not ok 1\n" unless $loaded;}
use W3C::Rdf::Algae2;
$loaded = 1;
print "ok 1 use W3C::Rdf::Algae2\n";

######################### End of black magic.

my $utf8 = ''; # ':utf8';
my $testNo = 2;

# Categories of tests:
my @qls = qw(Ephemoral0 SPARQL0 SPARQL1 Annotation0
	     );		# basic query languages
 # RDQL0 SeRQL0
my @opts = qw(Optional0 Optional1 Optional2
	     );		# query expressivity
my @dis = qw(Disjunction0 Disjunction1 Disjunction2 Disjunction3);
my @rules = qw(fwruleTest0 ); # fwruleTest1 		# rules
my @accs = qw(globTest1 datatype0); 			# other accessors
my @prfl = qw(ProfileQuery0 Hostname0); 		# profile extensions
my @coreTests = (@qls, @opts, @dis, @rules, @accs, @prfl);
my @tsTests = qw(Annotation1 Annotation3 );
my @borken_tsTests = qw(Annotation2 Annotation4 BRQL0 BRQL-Optional2 SPARQL-Optional2 );
my @otTests = qw(OrderTracking0 OrderTracking1 OrderTracking3 
		 OrderTracking4 OrderTracking5 OrderTracking6 Federate0 );
my @taTests = qw(ToxicAssoc0);
my @httpTests = qw(fwruleTest1);			# needs LWP
my @fingerTests = qw(Finger0 );
my @fileSystemTests = qw(FileSystem0);

# Select which categories to execute:
my @tests = @coreTests;
push (@tests, @tsTests) if ($test::tripleStore);
push (@tests, @otTests) if ($test::orderTracking);
push (@tests, @taTests) if ($test::toxicAssoc);
push (@tests, @httpTests) if ($test::http);
push (@tests, @fingerTests) if ($test::finger);
# push (@tests, @fileSystemTests);
my $count = @tests + 1;
print "2..$count\n";

# and execute them.
foreach my $test (@ARGV ? @ARGV : @tests) {
    &doTest($testNo++, "test/${test}-alg.sh");
}

sub doTest {
    my ($testNo, $test) = @_;
    local $/ = undef;
    if (!open (TEST, "<$utf8", $test)) {
	warn "can't open $test: $!";
	return;
    }
    my $script = <TEST>;
    close TEST;
    my $extraArgs = '';
    if ($script =~ m/\n\# Extra Arguments:\n(.*?\n)\n/s) {
	$extraArgs = $1;
	$extraArgs =~ s/^\# //gm;
	$extraArgs =~ s/\n/ /gm;
    }
    if ($script =~ m/\n\# Table Results:\n(.*?\n)\n/s) {
	if (!&passRun($1, $test, $extraArgs)) {
	    warn "not ok $testNo $test";
	} elsif ($script =~ m/\n\# ResultSet Results:\n(.*?\n)\n/s && 
		 !&passRun($1, $test, "--reportParm -resultSet=1 $extraArgs")) {
	    warn "not ok $testNo $test (ResultSet)";
	} else {
	    print "ok $testNo $test\n";
	}
    } else {
	warn "unable to find \"# Table Results:\" in $test";
	warn "not ok $testNo $test";
    }
}

sub passRun {
    my ($expected, $test, $parms) = @_;
    $expected =~ s/^\# //gm;
    my $expectedS = &reorder($expected);
    my $run = "(cd bin && perl \"-I../blib/lib\" \"-I../blib/arch\" ./algae $parms \@../$test)";
    if (!open (RUN, "-|$utf8", "$run")) {
	warn "can't run $run: $!";
	return;
    }
    my $out = <RUN>;
    close RUN;
    my $outS = &reorder($out);
    if ($outS ne $expectedS) {
	warn "expected:\n$expected\n\ngot:\n$out\n";
	return 0;
    } else {
	return 1;
    }
}

sub reorder {
    my ($unsorted) = @_;
    $unsorted =~ s/\_\:(\d+)/\_\:X/g;
    return join("\n", sort split (/\n/, $unsorted));
}

