#!perl

use strict;
use warnings;
use Pod::Usage;
use Getopt::Long;
use UNIVERSAL::require;
use Argon;
use Argon::Manager;
use Argon::Worker;

# Determine type of service to run
my $kind = shift @ARGV;
unless (defined $kind && $kind =~ /manager|worker/) {
    pod2usage({
        -message => 'Expected one of [ worker | manager ]',
        -exitval => 1,
        -verbose => 1,
    });
}

# Get options
my $help;
my $verbose;
my %opt = (
    port     => undef,
    host     => undef,
    manager  => undef,
    workers  => undef,
    max_reqs => undef,
);

GetOptions(
    'help'           => \$help,
    'verbose'        => \$verbose,
    'host=s'         => \$opt{host},
    'port=i'         => \$opt{port},
    'workers=i'      => \$opt{workers},
    'max_requests=i' => \$opt{max_requests},
    'manager=s'      => \$opt{manager},
) or pod2usage(1);

$help && pod2usage(0);

$Argon::LOG_LEVEL = $Argon::LOG_LEVEL | $Argon::LOG_DEBUG
    if $verbose;

# Clean up host
$opt{host} = '127.0.0.1' if !defined $opt{host} || $opt{host} eq 'localhost';

# Filter out undefined options
%opt = map { $_ => $opt{$_} } grep { defined $opt{$_} } keys %opt;

# Validate options
pod2usage('invalid options for manager')
    if $kind eq 'manager' && @opt{'workers', 'max_reqs', 'manager'};

my $class = $kind eq 'manager' ? 'Argon::Manager' : 'Argon::Worker';
$class->require;

my $service = $class->new(%opt);
$service->start;

exit 0;
__END__

=head1 NAME

argon - run an Argon service

=head1 SYNOPSIS

    argon manager --host 127.0.0.1 --port 8000
    argon worker  --host 127.0.0.1 --port 8001 --manager 127.0.0.1:8000 --workers 4 --max_requests 100

=head1 DESCRIPTION

Starts an Argon service node.

=head1 OPTIONS

=over

=item help

Prints out this help text.

=item verbose

When specified, turns on extra logging.

=item host

IP address of the host interface on which to listen. Defaults to 127.0.0.1.

=item port

Port number on which to listen. Defaults to an OS-assigned port.

=item workers

The number of worker processes to start. Defaults to the number of CPUs present
on the system. Applies only to workers.

=item max_requests

The maximum number of tasks a worker may handle before it is restarted. If not
specified, worker processes are never considered exhausted. Applies only to
workers.

=item manager

The address of the manager process in the format host:port. If not specified,
the worker is run in standalone mode. Applies only to workers.

=back
