package Catalyst::Helper::FastCGI::ExternalServer;

use strict;
use warnings;

use Catalyst::Utils;

use Cwd qw/realpath/;
use DateTime;
use File::Spec;
use Getopt::Long;

=head1 NAME

Catalyst::Helper::FastCGI::ExternalServer - FastCGI daemon start/stop script for using FastCgiExternalServer

=head1 VERSION

Version 0.031

=cut

our $VERSION = '0.031';

=head1 SYNOPSIS

In your helper script

	./script/myapp_create.pl FastCGI::ExternalServer [options]

=head2 OPTIONS

  Options:

    l=[val] listen=[val] (required)

      Socket path to listen on
      (defaults to standard input)
      can be HOST:PORT, :PORT or a
      filesystem path

    n=[val] nproc=[val] (optional)

      specify number of processes to keep
      to serve requests (defaults to 1, requires -listen)

    p=[val] pidfile=[val] (optional)

      specify filename for pid file
      (requires -listen)
      default is /var/run/myapp.pid

    u=[val] user=[val] (optional)

      specify username of executiong fastcgi
      default is root

    o=[val] logfile=[val] (optional)

      specify logfile path
      default is /dev/null

    M manager (optional)

      specify alternate process manager
      (FCGI::ProcManager sub-class)
      or empty string to disable

    e=[key1:val1,key2:val2...] env=[key1:val1,key2:val2...] (optional)

      specify additional environment variables

=head1 DESCRIPTION

This module allows configuration using /etc/sysconfig/myapp.
First make a file called /etc/sysconfig/myapp and then write some variables in it.
The variables that you add to the file will automatically override the environment variables.

=head1 METHODS

=head2 mk_stuff

generate init script

=cut

sub mk_stuff {
    my ( $self, $helper, @args ) = @_;

		my $config = {
				listen => undef,
				nproc => 1,
				pidfile => undef,
				manager => undef,
				env => {},
				user => 'root',
				logfile => '/dev/null',
				app => $helper->{app},
				author => $helper->{author},
				home => realpath($helper->{base}),
				appprefix => Catalyst::Utils::appprefix($helper->{app}),
				date => DateTime->now->ymd,
				version => __PACKAGE__->VERSION
		};

		$self->_parse_args($config, @args);
		
		$config->{script} = $config->{appprefix} . "_fastcgi_server.sh";
		$config->{fastcgi_script} = $config->{appprefix} . "_fastcgi.pl";

		my $script_file = File::Spec->catfile($helper->{base}, 'script', $config->{script});

		# print dump $config;
		# return;
		
		$helper->render_file('script', $script_file, $config);
		chmod 0755, $script_file;
}

sub _parse_args {
		my ($self, $config, @args) = @_;

		local @ARGV = ();

		foreach (@args) {
				my ( $key, $value ) = split /=/;
				$key ||= $_;

				push(@ARGV, "--$key");
				push(@ARGV, $value) if (defined $value);
		}

		my $listen = undef;
		my $nproc = 1;
		my $pidfile = File::Spec->catfile('/var/run', $config->{appprefix} . '.pid');
		my $manager = undef;
		my $daemon = undef;
		my $env = undef;
		my $user = 'root';
		my $logfile = '/dev/null';
		
		GetOptions(
				'listen|l=s'  => \$listen,
				'nproc|n=i'   => \$nproc,
				'pidfile|p=s' => \$pidfile,
				'manager|M=s' => \$manager,
				'env|e=s'     => \$env,
				'user|u=s'    => \$user,
				'logfile|o=s' => \$logfile
		);

		$config->{listen} = realpath($listen) if ($listen);
		$config->{nproc} = int $nproc if ($nproc);
		$config->{pidfile} = realpath($pidfile) if ($pidfile);
		$config->{manager} = $manager if ($manager);
		$config->{user} = $user if ($user);
		$config->{logfile} = realpath($logfile) if ($logfile);
		$config->{env}    = ($env) ? {
				map {split /:/} 
				split /,/ => $env
		} : {};

		
}

=head1 AUTHORS

=over 2

=item Toru Yamaguchi, C<< <zigorou at cpan.org> >>

Making this module.

=item Naoya Sano, C<< <sano at naoya.net> >>

Making init script template for FedoraCore, RedHat.

=item Daniel Burke

Supporting Debian, Ubuntu.

=back

=head1 THANKS

=over 2

=item Songhee Han

=back

=head1 BUGS

Please report any bugs or feature requests to
C<bug-catalyst-helper-fastcgi-externalserver at rt.cpan.org>, or through the web interface at
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Catalyst-Helper-FastCGI-ExternalServer>.
I will be notified, and then you'll automatically be notified of progress on
your bug as I make changes.

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Catalyst::Helper::FastCGI::ExternalServer

You can also look for information at:

=over 4

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/Catalyst-Helper-FastCGI-ExternalServer>

=item * CPAN Ratings

L<http://cpanratings.perl.org/d/Catalyst-Helper-FastCGI-ExternalServer>

=item * RT: CPAN's request tracker

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Catalyst-Helper-FastCGI-ExternalServer>

=item * Search CPAN

L<http://search.cpan.org/dist/Catalyst-Helper-FastCGI-ExternalServer>

=back

=head1 ACKNOWLEDGEMENTS

=head1 COPYRIGHT & LICENSE

Copyright 2006 Toru Yamaguchi, all rights reserved.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=cut

1;    # End of Catalyst::Helper::FastCGI::ExternalServer

__DATA__

__script__
#!/bin/bash
#
# [% script %] : [% appprefix %] fastcgi daemon start/stop script
#
# version : [% version %]
#
# chkconfig: 2345 84 16
# description: [% appprefix %] fastcgi daemon start/stop script
# processname: fcgi
# pidfile: [% pidfile %]
#
# [% date %] by [% author %]

# Load in the best success and failure functions we can find
if [ -f /etc/rc.d/init.d/functions ]; then
    . /etc/rc.d/init.d/functions
else
    # Else locally define the functions
    success() {
        echo -e "\n\t\t\t[ OK ]";
        return 0;
    }

    failure() {
        local error_code=$?
        echo -e "\n\t\t\t[ Failure ]";
        return $error_code
    }
fi

RETVAL=0
prog="[% appprefix %]"
[% UNLESS user == "root" %]SU=su
EXECUSER=[% user %][% END %]
EXECDIR=[% home %]
PID=[% pidfile %]
LOGFILE=[% logfile %]
PROCS=[% nproc %]
SOCKET=[% listen %]

# your application environment variables
[% FOREACH item IN env %]export [% item.key %]="[% item.value %]"
[% END %]

if [ -f "/etc/sysconfig/"$prog ]; then
		. "/etc/sysconfig/"$prog
fi

start() {
    if [ -f $PID ]; then
        echo "already running..."
        return 1
    fi
# Start daemons.
    echo -n $"Starting [% app %]: "
    echo -n "["`date +"%Y-%m-%d %H:%M:%S"`"] " >> ${LOGFILE}
		if [ "$USER"x != "$EXECUSER"x ]; then
			[% UNLESS user == "root" %]$SU -c "([% END %]cd ${EXECDIR};script/[% fastcgi_script %] -n ${PROCS} -l ${SOCKET} -p ${PID} -d >> ${LOGFILE} 2>&1[% UNLESS user == "root" %])" $EXECUSER [% END %]
		else
			cd ${EXECDIR}
			script/[% fastcgi_script %] -n ${PROCS} -l ${SOCKET} -p ${PID} -d >> ${LOGFILE} 2>&1
		fi
    RETVAL=$?
    [ $RETVAL -eq 0 ] && success || failure $"$prog start"
    echo
    return $RETVAL
}
stop() {
        # Stop daemons.
    echo -n $"Shutting down [% app %]: "
		echo -n "["`date +"%Y-%m-%d %H:%M:%S"`"] " >> ${LOGFILE}
    /bin/kill `cat $PID 2>/dev/null ` >/dev/null 2>&1 && (success; echo "Stoped" >> ${LOGFILE} ) || (failure $"$prog stop";echo "Stop failed" >> ${LOGFILE} )
    /bin/rm $PID >/dev/null 2>&1
    RETVAL=$?
    echo
    return $RETVAL
}
status() {
# show status
    if [ -f $PID ]; then
        echo "${prog} (pid `/bin/cat $PID`) is running..."
    else
        echo "${prog} is stopped"
    fi
    return $?
}
restart() {
    stop
    start
}
# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    status)
        status
        ;;
    *)
        echo $"Usage: $0 {start|stop|restart|status}"
        exit 1
esac
exit $?
