#!/usr/bin/perl -w

use lib "tools";
use lib "../tools";
use File::Basename;
use RDQL;

my $db = "dawgtest";

my $using = " USING rs FOR <http://www.w3.org/2001/sw/DataAccess/tests/result-set#>".
	          " mf FOR <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#>".
		  " qt FOR <http://www.w3.org/2001/sw/DataAccess/tests/test-query#>".
		  " dt FOR <http://www.w3.org/2001/sw/DataAccess/tests/test-dawg#>";

my $rdql = new RDQL(database => $db);
$rdql->set("max_comp", 100000);

if (@ARGV == 0) {
	die "Usage: $0 [--include-data] <manifest-file> ...\n";
}

$date = `date -I`;
chomp $date;

my %done;

$contents = "";
$body = "";
@manifests = ();

while ($file = shift) {
	if ($file eq "--include-data") {
		$include_data = 1;
		next;
	}

	$file =~ s/\/+/\//g;

	next if $done{$file};
	$done{$file} = 1;

	$datadir = dirname($file);

	#$xmlfile = $file;
	#$xmlfile =~ s(data/)(data-xml/);
	#$xmlfile =~ s(.n3$)(.rdf);
	#push(@manifests, "          <li><a href=\"$file\">$file</a> <a href=\"$xmlfile\">[RDF/XML version]</a></li>");
	push(@manifests, "          <li><a href=\"$file\">$file</a></li>");
	$cmd = "tstore_import --database=$db -m test: -f $file";
	print STDERR "reading $file\n";
	$out = `$cmd 2>&1`;
	if ($out) {
		print "$cmd: $out";
		next;
	}
	$cmd = "tstore_rebuild_taxonomy --database=$db";
	system($cmd);
	my $rows = $rdql->query(<<EOQ
SELECT ?list
WHERE (?manifest, <mf:entries>, ?list)
$using
EOQ
	);
	for $row (@{$rows}) {
		%cols = %{$row};
		&printEntry($cols{'?list'});
	}
}

$manifests = join("", @manifests);

$dollar = '$';

print <<EOB;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>DAWG Testcases</title>
    <link rel="stylesheet" type="text/css" href="http://www.w3.org/StyleSheets/TR/base.css" />
    <link rel="stylesheet" type="text/css" href="tests.css" />
  </head>
  <body>
    <h1>DAWG Testcases</h1>
    <dl>
      <dt>Document Editor</dt>
      <dd><a href="http://inanna.ecs.soton.ac.uk/">Steve Harris</a> &ndash; 
      IAM, University of Southampton</dd>

      <dt>Version:</dt>
      <dd><code>\$Revision: 1.23 $dollar</code></dd>
    </dl>

    <p class="copyright"><a href="
    http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> &copy; 2004 <a href="http://www.w3.org/"><acronym title=" World Wide Web Consortium">W3C</acronym></a><sup>&reg;</sup> (<a href="http://www.csail.mit.edu/"><acronym title="Massachusetts Institute of Technology">MIT</acronym></a>,
    <a href="http://www.ercim.org/"><acronym title="European Research Consortium for Informatics and Mathematics">ERCIM</acronym></a>,
    <a href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved. W3C
    <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
    <a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">
    trademark</a>, and <a
    href="http://www.w3.org/Consortium/Legal/copyright-documents"> document
    use</a> rules apply.</p>

    <hr title="Separator for header" />

    <p><strong>Abstract.</strong> This document lists a selection of queries that have been used in the discussions of the RDF <a href="http://www.w3.org/2001/sw/DataAccess/">Data Access Working Group</a>.</p>
    <p>Last updated $date</p>
    <hr />
    <h2>Source files</h2>
    <p>This document is automatically built from the manifest files. Relevant files are:</p>
    <dl>
      <dt>Schema and documentation</dt>
      <dd>
        <ul>
          <li><a href="README.html">README</a></li>
          <li><a href="result-set.n3">result-set.n3</a></li>
          <li><a href="test-dawg.n3">test-dawg.n3</a></li>
          <li><a href="test-manifest.n3">test-manifest.n3</a></li>
          <li><a href="test-query.n3">test-query.n3</a></li>
        </ul>
      </dd>
      <dt>Manifests</dt>
      <dd>
        <ul>
$manifests
        </ul>
      </dd>
      <dt>Source archives</dt>
      <dd>
        <ul>
          <li><a href="data.tar.gz">data.tar.gz</a></li>
          <li><a href="data.zip">data.zip</a></li>
          <li><a href="data-xml.tar.gz">data-xml.tar.gz</a></li>
          <li><a href="data-xml.zip">data-xml.zip</a></li>
        </ul>
      </dd>
    </dl>
EOB

print "   <hr />\n";
print "   <h2>Contents</h2>\n";
print "   <dl>\n";
print $contents;
print "   </dl>\n";
print "   <hr />\n";
print $body;

print <<EOB;
  </body>
</html>
EOB

sub printEntry {
	local($uri) = @_;

	my $listq = $rdql->query(<<EOQ
SELECT ?first, ?rest
WHERE ($uri, <rdf:first>, ?first)
      ($uri, <rdf:rest>, ?rest)
EOQ
	);

	$row = @{$listq}[0];
	if (!$row) {
		return;
	}
	%cols = %{$row};
	$this = $cols{'?first'};
	$rest = $cols{'?rest'};

	my $rows = $rdql->query(<<EOQ
SELECT ?p, ?o
WHERE ($this, ?p, ?o)
EOQ
	);
	%data = ();
	for $row (@{$rows}) {
		%cols = %{$row};
                $p = &valof($cols{'?p'});
		$p =~ s/.*?#//;
		#print "-- $p --\n";
		$data{$p} = $cols{'?o'};
	}

	if ($data{'name'}) {
		my $name = &valof($data{'name'});
		my $targ = "\L$name";
		$targ =~ s/[^a-z0-9]+/-/g;
		if ($data{'type'} eq '<http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#TestBadSyntax>') {
			$name .= " [negative]"
		}
		$name = &escape($name);
		$body .= "\n    <h2><a name=\"$targ\">$name</a></h2>\n";
		$contents .= "    <dt><a href=\"#".$targ."\">$name</a></dt>\n";
	} else {
		$body .= "    <h2>unknown test</h2>\n";
	}
	if ($data{'approval'}) {
		$aval = &valof($data{'approval'});
		$aval =~ s/.*?#//;
		$body .= "    <div class=\"approval\">$aval";
		if ($data{'approvedBy'}) {
			my $ab = &valof($data{'approvedBy'});
			$body .= ' by <a href="'.$ab.'">'.$ab."</a></div>\n";
			$contents .= "    <dd><a href=\"$ab\">$aval</a></dd>\n";
		} else {
			$body .= "</div>\n";
			$contents .= "    <dd>$aval</dd>\n";
		}
	}
	if ($data{'comment'}) {
		$body .= "    <p>".valof($data{'comment'})."</p>\n";
		$contents .= "    <dd><p>".valof($data{'comment'})."</p></dd>\n";
	}
	if ($data{'action'}) {
		$quri = valof($data{'action'});

		my $qq = $rdql->query(<<EOQ
SELECT ?query
WHERE (<$quri>, <qt:query>, ?query)
$using
EOQ
		);
		my $first = 1;
		for $row (@{$qq}) {
			%cols = %{$row};
			my $dq = $rdql->query(<<EOQ
SELECT ?data
WHERE (<$quri>, <qt:data>, ?data)
$using
EOQ
			);
			$datafn = $dq->[0]{'?data'};

			if ($datafn) {
				if ($first) {
					$body .= "    <h3>Data</h3>\n    <p>\n";
					$first = 0;
				}
				$datafn = &valof($datafn);
				$datafn =~ s/file:/$datadir\//;
				$datafn =~ s/test:/$datadir\//;
				$datafn =~ s/\/+/\//g;
				$body .= "      <a href=\"$datafn\">$datafn</a><br />\n";
				if ($include_data) {
					$body .= "    </p>\n";
					$body .= "    <div class=\"query\">";
					open(D, $datafn) || die "cannot open '$datafn' for printing: $!";
					@d = <D>;
					close D;
					map {$_ = &escape($_)} @d;
					map {s/\s*$/\n/} @d;
					eval {$d[@d-1] =~ s/\s+$//;}; if ($@) {my $lineNo = @d-1; warn "$datafn:$lineNo $@\n";}
					$body .= join("", @d);
					$body .= "</div>\n";
					$body .= "<p>\n";
				}
			}
		}

		if (!$first) {
			$body .= "    </p>\n";
		}

		$body .= "    <h3>Query</h3>\n";
		$query = &valof($cols{'?query'});
		$query =~ s/file:/$datadir\//;
		$query =~ s/test:/$datadir\//;
		$query =~ s/\/+/\//g;
		$body .= "      <a href=\"$query\">$query</a><br />\n";
		$body .= "    <div class=\"query\">";
		if (open(Q, $query)) {
		    @q = <Q>;
		    close Q;
		    map {$_ = &escape($_)} @q;
		    map {s/\s*$/\n/} @q;
		    eval {$q[@q-1] =~ s/\s+$//;}; if ($@) {warn "$query: $@\n";}
		    $body .= join("", @q);
		} else {
		    $body .= "cannot open '$query' for printing: $!";
		    warn "cannot open '$query' for printing: $!\n";
		}
		$body .= "</div>\n";
	}
	if ($data{'result'}) {
		$body .= "    <h3>Results</h3>\n";
		$fn = valof($data{'result'});
		$fn =~ s/file:/$datadir\//;
		$fn =~ s/test:/$datadir\//;
		&printRes($fn);
	}

	&printEntry($rest) if $rest;
}

sub printRes {
	local @files = @_;

	while ($file = shift @files) {
		$file =~ s/\/+/\//g;

		$cmd = "tstore_import --database=$db -m test:res -f $file";
		eval {$out = `$cmd 2>&1`;
		      if ($out) {
			  warn "$cmd: $out";
		      }
		  };
print STDERR "reading ".$file."\n";
		$cmd = "tstore_rebuild_taxonomy --database=$db";
		system($cmd);
		my $rows = $rdql->query(<<EOQ
SELECT ?sol
WHERE (?sol, <rdf:type>, <rs:ResultSet>)
$using
EOQ
		);
		$body .= "    <p><a href=\"$file\">$file</a></p>\n";
		for $row (@{$rows}) {
			%cols = %{$row};
			&printSet($cols{'?sol'});
		}
	}
}

sub printSet {
	local($uri) = @_;

	my @resvar = ();

	my $rows = $rdql->query(<<EOQ
SELECT ?var
WHERE ($uri, <rs:resultVariable>, ?var)
$using
EOQ
);
	$body .= "    <table class=\"results\">\n";
	$body .= "      <tbody>\n";
	$body .= "        <tr>";
	for $row (@{$rows}) {
		%cols = %{$row};
                $var = &valof($cols{'?var'});
		$body .= "<th>".valof($var)."</th>";
		push @resvar, $var;
	}
	$body .= "</tr>\n";

	my %resrow;

	$rows = $rdql->query(<<EOQ
SELECT ?sol, ?var, ?val
WHERE (?sol, <rs:binding>, ?binding)
      (?binding, <rs:variable>, ?var)
      (?binding, <rs:value>, ?val)
$using
EOQ
);
	my $rr;
	my @order;

	for $row (@{$rows}) {
		my %cols = %{$row};
		my $sol = $cols{'?sol'};
		my $var = $cols{'?var'};
		my $val = $cols{'?val'};
		if ($resrow{$sol}) {
			$rr = $resrow{$sol};
		} else {
			$rr = {};
			$resrow{$sol} = $rr;
		}
		$rr->{valof($var)} = $val;
		if (!grep(/^$sol$/, @order)) {
			push(@order, $sol);
		}
	}
	for $k (@order) {
		$body .= "      <tr>";
		$rr = $resrow{$k};
		for $var (@resvar) {
			if ($rr->{$var}) {
				$body .= "<td>".escape($rr->{$var})."</td>";
			} else {
				#$body .= "<td>NULL</td>";
				$body .= "<td></td>";
			}
		}
		$body .= "</tr>\n";
	}
		
	$body .= "      </tbody>\n";
	$body .= "    </table>\n";
}

sub valof {
	local ($v) = @_;

	$v =~ s/^<(.*)>$/$1/;
	$v =~ s/^"(.*)"$/$1/;

	return $v;
}

sub escape {
	local ($v) = @_;

	$v =~ s/&/\&amp;/g;
	$v =~ s/</\&lt;/g;
	$v =~ s/>/\&gt;/g;

	return $v;
}
