# -*- perl -*-
eval "exec perl $0 $*" 
  if 0;

use Socket;
use Getopt::Long;

# Usage string
my $usage = 
  "usage: xesclient [options] [file]\n" .
  "       xesclient -help for help";

# Options parsing
exit 1 unless GetOptions("help",
			 "verbose",
			 "delay=i",
			 "host=s",
			 "port=i",
			 "infofile=s");

# Option analysis
if (defined $opt_help) {
  warn <<'HELP';
 NAME
    xesclient - Client for xes server.

SYNOPSIS
    xesclient [options] [FILE]

DESCRIPTION
    xesclient connects to a Xes server (Xes simulator launched
    with -server option, and sends csimul stimuli.

    xesclient reads the stimuli either from FILE or stdin if
    FILE is not specified.

OPTIONS
    Options may be abbreviated.

    -host name: host running the Xes server. Mandatory.

    -port num : port number of the Xes server. Mandatory.

    -infofile file: 
                read host and port information if file.

    -verbose  : when reading from a file, prints on stdout
		the stimuli.

    -delay num: sleep for num second between each stimuli
                when reading a file.

    -help     : this help.

AUTHOR
    Xavier Fornari
 
HELP
  ;
  exit 0;
}


die "*** $usage\n" 
  unless (defined($opt_infofile) || (defined($opt_host) && defined($opt_port)));
my $remote;
my $port;

if (defined $opt_infofile ) {
  $opt_infofile .= '.esp' unless $opt_infofile =~ /\.esp$/;
  open (INFO, $opt_infofile) or die "*** Cannot open $opt_infofile\n";
 INFO: {
    while (<INFO>) {
      m/(\S+)\s+(\d+)/ && do {
	($remote, $port) = ($1, $2);
	last INFO;
      };
    }
    die "*** Bad .esp file\n";
  }
  close(INFO);
}
else {
  $remote = $opt_host;
  $port = $opt_port;
}

# batch mode options
$batch_mode = 0;
if ( @ARGV > 0 ) {
  -e $ARGV[0] || die "*** no such file: $ARGV[0]\n";
  $batch_mode = 1;
  $| = 1;
}
$opt_verbose = $batch_mode && defined($opt_verbose);

die "*** wrong delay: $opt_delay\n"
  if (defined($opt_delay) && $opt_delay <= 0);


# opening socket
my $iaddr;
$iaddr = inet_aton($remote) or die "*** no host: $remote";

my $paddr = sockaddr_in($port, $iaddr);

my $proto = getprotobyname('tcp');

socket(SOCK, PF_INET, SOCK_STREAM, $proto) or die "*** socket: $!\n";
connect(SOCK, $paddr) or die "*** connect: $!\n";

select(SOCK);
$| = 1;

sub handler {
  local($sig) = @_;
  print STDERR "### Closing connection\n";
  close(SOCK) or die "*** close: $!\n";
  exit 0;
}

$SIG{INT} = 'handler';

# simulation
my $counter = 0;
print STDOUT '> ' unless $batch_mode;
while (<>) {
  print SOCK;
  if ( $batch_mode ) {
      print STDOUT if $opt_verbose;
      sleep $opt_delay if defined $opt_delay;
  }
  else {
    print STDOUT '> ';
  }
  $counter++;
}
print STDOUT "--- Simulation ended. $counter inputs sent\n";

close(SOCK) or die "*** close: $!\n";
