# A simple, generic TCP server.
# Implements an Internet socket server that
# spawns connection managers of a given class.
# Surprisingly reusable, considering it was a
# one-off example for the OSCON 2004 tutorial.
# Copyright 2004 by Rocco Caputo.  Free software.
# Same terms as Perl itself.  Have fun!

package Server;

use warnings;
use strict;

use POE qw(Wheel::SocketFactory);

sub spawn {
  my ($class, %param) = @_;

  require "$param{ConnClass}.pm";
  $param{ConnClass}->import();

  POE::Session->create(
    inline_states => {
      _start     => \&handle_start,
      connection => \&handle_connect,
      error      => \&handle_error,
    },
    args => [ \%param ],
  );
}

sub handle_start {
  my ($heap, $param) = @_[HEAP, ARG0];
  $heap->{class} = $param->{ConnClass};
  $heap->{server} =
    POE::Wheel::SocketFactory->new(
      %$param,
      SuccessEvent => "connection",
      FailureEvent => "error",
      Reuse        => 1,
    );
}

sub handle_connect {
  $_[HEAP]->{class}->spawn($_[ARG0]);
}

sub handle_error {
  my $heap = $_[HEAP];
  my ($syscall, $errno, $text) = @_[ARG0..ARG2];
  warn "Server: $syscall error $errno: $text\n";
  delete $heap->{server};
}

sub run {
  POE::Kernel->run();
}

1;
