#!/usr/bin/perl -w

use IO::Socket;

require 'node.pl';


# ------------------------------------------------------------------------------
# globals

use vars qw( $debug
	     $con
	     $msg_type
	     $dir
	     $ref
	     %fields
	     $body );


# ------------------------------------------------------------------------------
# constants

my $MAX_LISTEN          = 20;
my $HELLO_TIMEOUT       = 5;
my $INACTIVITY_TIMEOUT  = 10;


# ------------------------------------------------------------------------------
# command line arguments

die "syntax: $0 [-d|-D] listen_port" unless @ARGV == 1;
my $hub_port = shift;


# ------------------------------------------------------------------------------
# file my variables

# sequence number for my_refs
my $my_ref_seq = 1;


# ------------------------------------------------------------------------------
# listening socket
my $sock_listen = IO::Socket::INET->new( Proto     => 'tcp',
					 LocalPort => $hub_port,
					 Listen    => $MAX_LISTEN,
					 Reuse     => 1 )
    or die "cannot open listening socket: $!";


# ------------------------------------------------------------------------------
# 'listen' connection handler

set_readh('listen', sub {
    accept_connection('new');
});


# ------------------------------------------------------------------------------
# 'new' connection handler

set_conh('new',
    START => sub {
      { my $con = $con;
	set_timeout($HELLO_TIMEOUT, sub {
	    message($con, "timeout: time limit for connection has expired");
	    abort_connection($con);
	}); }
    },

    hello => sub {
	send_message('welcome', '<', $ref);
	set_con_state('active');
    },

    STOP => sub {
	cancel_timeout();
    }
);


# ------------------------------------------------------------------------------
# 'active' connection handler

set_conh('active',
    START => sub {
      { my $con = $con;
	set_timeout($INACTIVITY_TIMEOUT, sub {
	    message($con, "timeout: time limit for inactivity has expired");
	    abort_connection($con);
	}); }	
    },

    BEFORE => sub {
	$conv = $conv{"$dir $ref"};
	reset_timeout();
    },

    fortune => sub {
	send_message('fortune', '<', $ref, scalar(`/usr/games/fortune`));
    },

    STOP => sub {
	cancel_timeout();
    },
);


# ------------------------------------------------------------------------------
# begin work

install_signal_handlers();

add_connection($sock_listen, 'listen');

main_loop();
