package AmphetaDesk::WebServer;
###############################################################################
# AmphetaDesk                                           (c) 2000-2002 Disobey #
# morbus@disobey.com                      http://www.disobey.com/amphetadesk/ #
###############################################################################
# ABOUT THIS PACKAGE:                                                         #
#   This package controls our webserver daemon - both in regards to over-     #
#   riding the defaults of the HTTP::Daemon proces tokens, as well as         #
#   providing a blackbox for our various webserver creation routines.         #
#                                                                             #
# LIST OF ROUTINES BELOW:                                                     #
#   product_tokens - overrides the HTTP::Daemon Server: name with our own.    #
#   start_radio_webserver - start a Radio webserver, and return the object.   #
#   start_webserver - starts the webserver, and returns the server object.    #
###############################################################################
#                            "Delete Yourself!"                               #
###############################################################################

use strict; $|++;
use HTTP::Daemon;
use AmphetaDesk::Settings;
use AmphetaDesk::Utilities;
require Exporter;
use vars qw( @ISA @EXPORT );
@ISA = qw( Exporter HTTP::Daemon );
@EXPORT = qw( start_webserver start_radio_webserver );

###############################################################################
# product_tokens - overrides the HTTP::Daemon Server: name with our own.      #
###############################################################################
# USAGE:                                                                      #
#   You don't. It overrides the HTTP::Daemon defaults.                        #
###############################################################################

sub product_tokens {
   my $app_v = get_setting("app_version");
   my $app_u = get_setting("app_url");
   my $app_o = get_setting("app_os");
   "AmphetaDesk/$app_v ($app_o; $app_u)";
}

###############################################################################
# start_radio_webserver - start a Radio listener, and return the object.      #
###############################################################################
# USAGE:                                                                      #
#   my $radio_daemon = start_radio_webserver;                                 #
#                                                                             #
# NOTES:                                                                      #
#   This routine merely starts up an HTTP::Daemon webserver on port 5335 for  #
#   the sole goal of listening to Radio Userland coffee mug subscriptions.    #
#                                                                             #
# RETURNS:                                                                    #
#   $daemon; an HTTP::Daemon server object.                                   #
#   0; if the internal Radio listener could not be started.                   #
###############################################################################

sub start_radio_webserver {

   # attempt to create the daemon port 5335. we pass the
   # arguments as a hash so that we can determine if we should 
   # bind to localhost, or allow outside connections. happy, quasi?
   my %daemon_args = ( LocalPort => 5335, ReuseAddr => 1, Timeout => .1 );
   $daemon_args{LocalAddr} = "127.0.0.1" unless get_setting("user_allow_nonlocal_conn");
   my $daemon = AmphetaDesk::WebServer->new( %daemon_args );

   # if we grabbed the socket, exit the loop, else make a note
   # and try the next one. if we did grab a port successfully,
   # set our template value so we know what port we're using.
   if ($daemon) { note("Successfully grabbed port 5335 for the internal Radio Userland webserver."); }
   else { note("There was a problem starting the internal Radio Userland listener: $!."); }

   # if we couldn't grab any of the sockets, then we need to exit.
   unless ($daemon) { note("Unfortunately, AmphetaDesk couldn't grab " .
                           "port 5335 for the local Radio Userland webserver. This isn't " .
                           "going to fix itself - please email " . get_setting("app_email") .
                           " with more information about your machine, OS, " .
                           "security software, etc.", 1); return 0; }

   # turn on autoflush. as of
   # IO::Socket 1.18, this is 
   # the default, but we leave
   # it on, just in case.
   $daemon->autoflush;
   return $daemon;

}

###############################################################################
# start_webserver - starts the webserver, and returns the server object.      #
###############################################################################
# USAGE:                                                                      #
#   my $daemon = start_webserver;                                             #
#                                                                             #
# NOTES:                                                                      #
#   This routine merely starts up an HTTP::Daemon webserver on one of three   #
#   possible ports and returns the webserver daemon object. Interaction with  #
#   this object takes place in the main AmphetaDesk.pm module.                #
#                                                                             #
# RETURNS:                                                                    #
#   $daemon; an HTTP::Daemon server object.                                   #
#   die; if the internal webserver could not be started.                      #
###############################################################################

sub start_webserver {

   # determine the three possible ports we can run on.
   my @possible_ports = ( get_setting("urls_port_default"),
                          get_setting("urls_port_secondary"),
                          get_setting("urls_port_tertiary") );

   # and loop through each port, hoping to grab one.
   my $daemon; foreach (@possible_ports) {

      # attempt to create the daemon on this port. we pass the
      # arguments as a hash so that we can determine if we should 
      # bind to localhost, or allow outside connections. happy, quasi?
      my %daemon_args = ( LocalPort => $_, ReuseAddr => 1, Timeout => .1 );
      $daemon_args{LocalAddr} = "127.0.0.1" unless get_setting("user_allow_nonlocal_conn");
      $daemon = AmphetaDesk::WebServer->new( %daemon_args );

      # if we grabbed the socket, exit the loop, else make a note
      # and try the next one. if we did grab a port successfully,
      # set our template value so we know what port we're using.
      if ($daemon) { note("Successfully grabbed port $_ for the internal webserver."); set_setting("urls_port", $_); last; }
      else { note("There was a problem starting the internal webserver on port $_: $!."); }
   }

   # if we couldn't grab any of the sockets, then we need to exit.
   unless ($daemon) { error("Unfortunately, AmphetaDesk couldn't grab " .
                            "any ports for the local webserver. This isn't " .
                            "going to fix itself - please email " . get_setting("app_email") .
                            " with more information about your machine, OS, " .
                            "security software, etc.", 1); exit; }

   # turn on autoflush. as of
   # IO::Socket 1.18, this is 
   # the default, but we leave
   # it on, just in case.
   $daemon->autoflush;
   return $daemon;

}

1;
