#!/usr/bin/perl

$REVISION = '$Id: algaeListener,v 1.2 2004/10/21 17:19:05 eric Exp $ ';

#Copyright Massachusetts Institute of technology, 2004.
#Written by Eric Prud'hommeaux for the World Wide Web Consortium

# $Id: algaeListener,v 1.2 2004/10/21 17:19:05 eric Exp $

use strict;

package Listener;

use Getopt::Long;
use IO::Socket;
use threads;
use threads::shared;

use W3C::Util::Exception qw(&throw &catch &DieHandler);
use W3C::Rdf::RdfApp;
use W3C::Rdf::Atoms qw($Value_NULL);

use vars qw($DEF_PORT $ACCEPTS);
($DEF_PORT, $ACCEPTS) = (9999, 10);

my $l = new Listener(@ARGV);
$l->execute();

sub new {
    my ($proto, $context) = @_;
    my $class = ref($proto) || $proto;
    my $self = {PORT => $DEF_PORT};
    bless ($self, $class);

    my $queryLangNames = {'Algae' => $QL_ALGAE, 
			  'RDQL' => $QL_RDQL, 
			  'SPARQL' => $QL_SPARQL, 
			  'RXQuery' => $QL_RXQuery, 
			  'SeRQL' => $QL_SeRQL};
    my $queryLang = $QL_ALGAE;
    my $port = $DEF_PORT;

    my ($help, $man);
    my $res = &GetOptions(
	'help|?' => \$help, 
	'lang|l=s' => sub {
	    local($SIG{"__DIE__"}) = \&DieHandler;
	    my (undef, $val) = @_;
	    if (exists $queryLangNames->{$val}) {
		$queryLang = $queryLangNames->{$val};
	    } else {
		my $langs = join(', ', keys %$queryLangNames);
		&throw(new W3C::Util::Exception(
				-message => 
				"\"$val\" not supported. Use one of $langs."));
	    }
	}, 
	'man' => \$man, 
	'port|p=i' => \$port, 
			  );
    $self->{PORT} = $port;
    &pod2usage(-exitstatus => 0, -verbose => 1) if $help;
    &pod2usage(-exitstatus => 0, -verbose => 2) if $man;
    return $self;
}

sub execute {
    my ($self) = @_;
    my $sock = IO::Socket::INET->new(Listen    => $ACCEPTS, 
				     LocalAddr => 'localhost', 
				     LocalPort => $self->{PORT}, 
				     Proto     => 'tcp', 
				     Reuse     => 1);
    print "listening on $self->{PORT}\n";
    my $quit = 0;
    while ((my $socket = $sock->accept()) && !$quit) {
	my $query;
	while ($query .= <$socket>) {
	    if ($query =~ m/^(.*?)\n\n(.*)$/sm || $query =~ m/^(.*?)\r\n\r\n(.*)$/sm) {
		my ($cur, $next) = ($1, $2);
		# print "checking \"$query\"\n";
		# print "execute ($cur)\n";
		$query = $next;
	    }
	}
	warn "lost connection";
	close($socket);
    }
}

__END__

=head1 NAME

algaeListener - TCP server to answer RDF queries.

=head1 SYNOPSIS

algaeListener [options]

=head1 OPTIONS

=over 8

=item B<-l|lang>

Language name of next query (eg. SPARQL, RDQL, Algae, SeRQL)

=item B<-help>

Print a brief help message and exit.

=item B<-man>

Send the manual page to the $PAGER and exit.

=item B<-p|port>

Listen on TCP port B<port>.

=back

=head1 DESCRIPTION

B<algaeListener> reads a series of queries on a specified B<port> in any of the B<supported languages>.

This module is part of the W3C::Rdf CPAN module.

=head1 AUTHOR

Eric Prud'hommeaux <eric@w3.org>

=head1 SEE ALSO

L<W3C::Rdf::Algae2>
L<W3C::Rdf::RdfDB>

=head1 COPYRIGHT

Copyright Massachusetts Institute of technology, 1998.

THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS
OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR
FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE
ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. 

COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. 

The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining 
to the software without specific, written prior permission. Title to copyright in this software and 
any associated documentation will at all times remain with copyright holders. 

=cut

