#!/usr/local/bin/perl -w
use strict;
use warnings;

our $VERSION = '0.0.13';


use File::Path;
use FindBin;
use Getopt::Long;
use Pod::Usage;
use YAML;

use Time::HiRes qw(usleep);

use lib "$FindBin::Bin/../lib";
use Proc::Launcher::Manager;

#
#_* Command-line options processing
#

my %options;

unless ( GetOptions ( '-start'      => \$options{start},
                      '-stop'       => \$options{stop},
                      '-restart'    => \$options{restart},
                      '-force'      => \$options{force},
                      '-supervisor' => \$options{supervisor},
                      '-tail:i'     => \$options{tail},
                      '-config'     => \$options{configfile},
                      '-daemon=s'   => \$options{daemon},
                      '-v|verbose!' => \$options{verbose},
                      '-help|?'     => \$options{help},
    )
) { pod2usage( -exitval => 1, -verbose => 1 ) }

if ( $options{help} ) {
    pod2usage( -exitval => 0, -verbose => 2 );
}

#
#_* Config
#

my $directory = join( "/", $ENV{HOME}, ".panctl" );
print "DIRECTORY: $directory\n";

# Make sure it worked:
unless ( -d $directory ) {
    mkpath( $directory );
}

# Config
my $configfile = $options{configfile} || join( '/', $directory, 'panctl.conf' );
unless ( -r $configfile ) {
    die "ERROR: config file not found: $configfile\n";
}

# Load
my $config = YAML::LoadFile( $configfile );

#
#_* Main
#
my $monitor = Proc::Launcher::Manager->new( app_name  => 'panctl',
                                            pid_dir   => $directory,
                                        );

print "\n";
for my $name ( keys %{ $config } ) {

    if ( $options{daemon} ) {
        next unless $options{daemon} eq "all" || $name =~ m/$options{daemon}/;
    }

    print "Loaded: $name: $config->{$name}->{description}\n";

    my $cmd = $config->{$name}->{command};

    #print "COMMAND $name: $cmd\n";

    $monitor->spawn( daemon_name  => $name,
                     start_method => sub { exec( $cmd ) },
                     debug        => $options{verbose},
                 );

}
print "\n";

if ( $options{start} ) {
    $monitor->start();
}
elsif ( $options{restart} && $options{force} ) {
    $monitor->stop();
    sleep 3;
    $monitor->force_stop();
    sleep 1;
    $monitor->start();
}
elsif ( $options{restart} ) {
    $monitor->stop();
    sleep 1;
    $monitor->start();
}
elsif ( $options{stop} && $options{force} ) {
    $monitor->force_stop();
}
elsif ( $options{stop} ) {
    $monitor->stop();
}

if ( $options{supervisor} ) {
    print "Starting the supervisor process...\n";
    $monitor->supervisor();
}

if ( defined $options{tail} ) {

    # we're sleeping for 1/10th of a second, so we have to take the
    # number of seconds specified * 10.
    my $max_count = $options{tail} ? $options{tail} * 10 : 0;

    # display all new log output to stdout
    my $count;
    while ( 1 ) {

        # if tail was passed an integer, quit after the specified
        # number of 1-second loops.
        if ( $max_count ) {
            $count++;
            last if $count > $max_count;
        }

        $monitor->read_log( sub { print "$_[0]\n" } );

        # sleep for .1 seconds
        usleep 100_000;
    }
}


__END__

