#!/usr/bin/perl

use qbit;

use Getopt::Long;
use Pod::Usage;
use FCGI;
use FCGI::ProcManager::Dynamic;
use Proc::Daemon;

my %args = ();
GetOptions(
    \%args,
    'help|?',
    'daemonize!',
    'lib-path=s@',
    'pid_fname=s',
    'listen=s',
    'backlog=i',
    'user=s',
    'pm_title=s',
    'n_processes=i',
        'min_nproc=i',
        'max_nproc=i',
        'delta_nproc=i',
        'delta_time=i',
        'max-requests=i',
);

pod2usage(1) if $args{'help'} || !exists($ARGV[0]);

if ($args{'lib-path'}) {
    require lib;
    lib->import(@{$args{'lib-path'}});
}

my $init_force_gettext_xs = $ENV{FORCE_GETTEXT_XS};

my $class_fname = $ARGV[0];
$class_fname =~ s/::/\//g;
$class_fname .= '.pm';
require $class_fname;

if ($args{'daemonize'}) {
    my $uid;
    if ($args{'user'}) {
        $uid = getpwnam($args{'user'});
        unless ($uid) {
            print gettext('User "%s" doesn\'t exists') . "\n";
            exit(1);
        }
    }

    my $daemon = Proc::Daemon->new(($uid ? (setuid => $uid) : ()));
    $daemon->Init();
}

my $defaults = {
    n_processes => 5,
    pm_title    => 'qbit_fcgi_starter',
    delta_time  => 60
};

my @saved_env_names = ('PORTO_NAME', 'TVMTOOL_LOCAL_AUTHTOKEN', grep {m/^SECRET_/} keys(%ENV));
my %saved_env = map {$_ => $ENV{$_}} @saved_env_names;

my $proc_manager = FCGI::ProcManager::Dynamic->new({
    map {$_ => $args{$_} // $defaults->{$_} }
      grep {defined( $args{$_} // $defaults->{$_} )}
          qw(
              n_processes
              min_nproc
              max_nproc
              delta_nproc
              delta_time
              max_requests

              pid_fname
              pm_title
          )
});

my $socket = FCGI::OpenSocket($args{'listen'} || ':9000', $args{'backlog'} || 5);
# TODO: remove
# This process should be started as partners:www-data. Waiting for deploy to fix it
if ($args{listen} && $ENV{PORTO_NAME}) {
    system("chown partners:www-data $args{listen}");
}
my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, $socket);

my $web_interface = $ARGV[0]->new();

$proc_manager->pm_manage();

my $n = 0;
while ($request->Accept() >= 0) {
    $proc_manager->pm_pre_dispatch();
    $ENV{FORCE_GETTEXT_XS} //= $init_force_gettext_xs;
    %ENV = (%ENV, %saved_env);
    $web_interface->run($request);
    $proc_manager->pm_post_dispatch();
    exit(0) if $args{'max-requests'} && ++$n >= $args{'max-requests'};
}

FCGI::CloseSocket($socket);

__END__

=head1 NAME

qbit_fcgi_starter

=head1 SYNOPSIS

qbit_fcgi_starter [options] class_name

Class "class_name" must be QBit::WebInterface::FastCGI descendant.

=head1 OPTIONS

=over 15

=item B<--daemonize>

Use if you want run as daemon.

=item B<--pm_title>

Change process manager process name.

=item B<--lib-path>

Directories with perl modules. Use several times if need.

=item B<--n_processes>

Count of process, default 10.

=item B<--pid_fname>

Write pid file.

=item B<--listen>

C<:port> - TCP connection or

C</path/filename> - UNIX socket.

=item B<--backlog>

Maximum length of the queue of pending connections.

=item B<--user>

Set daemon owner. (Only wiith --daemonize and run under root).

=item B<--max-requests>

Set max requests per child.

=item B<--help>

Show help message and exit.

=back

=head1 DESCRIPTION

Extract translatable strings from given input files.
