#!/usr/bin/perl
# ============================================================================
#             Copyright (c) 2009 Kevin L. Esteb All Rights Reserved
#
# TITLE:       supervisor
#
# ABSTRACT:    This program will supervise other processes.
#
# ENVIRONMENT: Perl v5.8.8
#
# PARAMETERS:  --help......Display this simple help message
#              --port......The port the Supervisor is listening on
#              --address...The address to bind too
#              --config....The config file to use
#              --pidfile...The filename to use for the pid file
#
# RETURNS:     0 - on success
#              1 - on failure
#
# Version      Author                                              Date
# -------      ----------------------------------------------      -----------
# 0.01         Kevin Esteb                                         11-Sep-2009
#
# ============================================================================
#

use strict;
use warnings;

our $VERSION = '0.01';

# ---------------------------------------------------------------------
# Required Modules
# ---------------------------------------------------------------------

use File::Pid;
use Getopt::Long;
use Supervisor::Controller;
use Supervisor::RPC::Server;
use Supervisor::ProcessFactory;

use Supervisor::Class
  version   => $VERSION,
  base      => 'Supervisor::Base',
  constants => 'DEFAULT_PORT DEFAULT_ADDRESS',
  constant => {
      handler => __PACKAGE__
  }
;

# ---------------------------------------------------------------------
# Global variables
# ---------------------------------------------------------------------

my $pid;
my $pidfile;

my $port = DEFAULT_PORT;
my $host = DEFAULT_ADDRESS;
my $config = 'supervisor.ini';

# ---------------------------------------------------------------------

sub setup {

    my $num;
    my $help;

    GetOptions(
        'help|h|?'  => \$help,
        'config=s'  => \$config,
        'port=s'    => \$port,
        'address=s' => \$host,
        'pidfile=s' => \$pidfile,
    );

    if ($help) {

        usage();
        exit(0);

    }

    # create a pid file

    if (defined($pidfile)) {

        $pid = File::Pid->new({file => $pidfile});
        if ($num = $pid->running()) {

            printf("supervisor is already running: %s\n", $num);
            exit 1

        }

        $pid->write();

    }

}

sub usage {

    my ($Script) = ( $0 =~ m#([^\\/]+)$# );
    my $Line = "-" x length( $Script );
    print << "EOT";

$Script
$Line
supervisor - A procedure to monitor other processes.
Version: $VERSION

  Usage:
    $0 [--help]
    $0 [--port] <port>
    $0 [--address] <address>
    $0 [--config] <filename>
    $0 [--pidfile] <filename>

    --help......Display this simple help message.
    --port......The port to listen on (default 9505)
    --address...The address to bind too (default localhost)
    --config....The configuration file to use
    --pidfile...The name of the pid file to use

    Examples:
      $0 --help
      $0 --config supervisor.ini

EOT

}

main: {

    my $supervisor;

    eval {

        setup();

        $supervisor = Supervisor::Controller->new(
            Name => 'Supervisor',
            Logfile => '/dev/stdout',
            Processes => Supervisor::ProcessFactory->load(
                Config => $config,
                Supervisor => 'Supervisor',
            ),
            RPC => Supervisor::RPC::Server->new(
                Name => 'RPC',
                Port => $port,
                Address => $host,
                Logfile => '/dev/stdout',
                Supervisor => 'Supervisor'
            )
        );

        $supervisor->run();
        $pid->remove() if (defined($pid));

        exit 0;

    }; if (my $ex = $@) {

        printf("%s\n", $ex);
        $pid->remove() if (defined($pid));

        exit 1;

    }

}

