#/*
# *  Copyright 2007-2010 hkrn <hikarin@users.sourceforge.jp>
# *
# *  Licensed under the Apache License, Version 2.0 (the "License");
# *  you may not use this file except in compliance with the License.
# *  You may obtain a copy of the License at
# *
# *      http://www.apache.org/licenses/LICENSE-2.0
# *
# *  Unless required by applicable law or agreed to in writing, software
# *  distributed under the License is distributed on an "AS IS" BASIS,
# *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# *  See the License for the specific language governing permissions and
# *  limitations under the License.
# */
#
# $Id: Server.pm 1901 2009-12-31 02:40:20Z hikarin $
#

package Img0ch::FCGI::Server;

use strict;
use CGI qw();
use FCGI qw();
use FCGI::ProcManager qw();
use Img0ch::Config qw();
use Img0ch::FCGI::Request qw();
use Img0ch::Maple qw();

Img0ch::Maple->load_application_modules();

sub run {
    my ( $iClass, $options ) = @_;

    my $iConfig            = Img0ch::Config->new();
    my $img0ch_config_path = $options->{img0ch_config_path};
    $iConfig->load($img0ch_config_path);
    my $iKernel = Img0ch::Maple->new($iConfig);

    while ( my ($ignore) = each %ENV ) {1}
    my $sock = FCGI::OpenSocket( $options->{fcgi_socket_path}, 100 )
        or die 'Cannot open FastCGI socket: ', $!, "\n";
    my $error = $options->{keep_stderr} ? \*STDOUT : \*STDERR;
    my $request = FCGI::Request( \*STDIN, \*STDOUT, $error, \%ENV, $sock,
        FCGI::FAIL_ACCEPT_ON_INTR() );

    require POSIX;
    my $pid = fork() and exit(1);
    my $nproc = Img0ch::Maple::intval( $options->{number_of_processes} ) || 3;
    my $FCGIPM = FCGI::ProcManager->new(
        {   n_processes => $nproc,
            pid_fname   => $options->{pid_file_path},
        }
    );

    open STDIN,  '+</dev/null' or die $!;    ## no critic
    open STDOUT, '>&STDIN'     or die $!;    ## no critic
    open STDERR, '>&STDIN'     or die $!;    ## no critic
    POSIX::setsid();
    $FCGIPM->pm_manage();

    my $img0ch_config_modified = 0;
SERVER:
    while ( $request->Accept() >= 0 ) {
        $FCGIPM->pm_pre_dispatch();

       #        my $modified = (stat($img0ch_config_path))[9];
       #        if ( ( $img0ch_config_modified ||= $modified ) < $modified ) {
       #            $FCGIPM->pm_die(
       #                '[', scalar(localtime(time())),
       #                '] restarted FastCGI application: ', $app
       #            );
       #        }
        eval {
            CGI->_reset_globals();
            my $q = $CGI::Q = CGI->new();
            my $script = $q->script_name();
            $script =~ s{\.cgi/?.*\z}{.cgi}xms;
            $script =~ s{.+/}{}xms;
            my $app = $iKernel->get_module_by_script($script)
                or die 'Cannot find module from script: ', $script, "\n";
            $app->new( $iKernel, $q )->run();
        };
        if ( my $errstr = $@ ) {
            $errstr = Img0ch::Maple::escape_html_entities($errstr);
            $errstr =~ s/\n/<br>/gxms;
            $errstr =~ s/\s/&nbsp;/gxms;
            print 'Content-type: text/html', "\n\n", $errstr, "\n";
        }
        $FCGIPM->pm_post_dispatch();
    }
}

1;
__END__
