/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/* For DEFAULT_PATH */
#define CORE_PRIVATE
#include "httpd.h"
#include "http_config.h"
#include "apr_strings.h"

#include "fcgid_pm.h"
#include "fcgid_pm_main.h"
#include "fcgid_conf.h"
#include "fcgid_proctbl.h"
#include "fcgid_proc.h"
#include "fcgid_spawn_ctl.h"

#define HAS_GRACEFUL_KILL "Gracefulkill"

static void
link_node_to_list(server_rec * main_server,
                  fcgid_procnode * header,
                  fcgid_procnode * node, fcgid_procnode * table_array)
{
    proctable_pm_lock(main_server);
    node->next_index = header->next_index;
    header->next_index = node - table_array;
    proctable_pm_unlock(main_server);
}

static apr_time_t lastidlescan = 0;
static void scan_idlelist(server_rec * main_server)
{
    /* 
       Scan the idle list 
       1. move all processes idle timeout to error list
       2. move all processes lifetime expired to error list
     */
    fcgid_procnode *previous_node, *current_node, *next_node;
    fcgid_procnode *error_list_header;
    fcgid_procnode *proc_table;
    apr_time_t last_active_time, start_time;
    apr_time_t now = apr_time_now();
    int idle_timeout, proc_lifetime;
    fcgid_server_conf *sconf =
        ap_get_module_config(main_server->module_config,
                             &fcgid_module);

    /* Should I check the idle list now? */
    if (procmgr_must_exit()
        || apr_time_sec(now) - apr_time_sec(lastidlescan) <=
        sconf->idle_scan_interval)
        return;
    lastidlescan = now;

    /* Check the list */
    proc_table = proctable_get_table_array();
    previous_node = proctable_get_idle_list();
    error_list_header = proctable_get_error_list();

    proctable_pm_lock(main_server);
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];
        last_active_time = current_node->last_active_time;
        start_time = current_node->start_time;
        idle_timeout = current_node->cmdopts.idle_timeout;
        proc_lifetime = current_node->cmdopts.proc_lifetime;
        if (((idle_timeout &&
              (apr_time_sec(now) - apr_time_sec(last_active_time) >
               idle_timeout))
             || (proc_lifetime
                 && (apr_time_sec(now) - apr_time_sec(start_time) >
                     proc_lifetime)))
            && is_kill_allowed(main_server, current_node)) {
            /* Set die reason for log */
            if (idle_timeout &&
                (apr_time_sec(now) - apr_time_sec(last_active_time) >
                 idle_timeout))
                current_node->diewhy = FCGID_DIE_IDLE_TIMEOUT;
            else if (proc_lifetime &&
                     (apr_time_sec(now) - apr_time_sec(start_time) >
                      proc_lifetime))
                current_node->diewhy = FCGID_DIE_LIFETIME_EXPIRED;

            /* Unlink from idle list */
            previous_node->next_index = current_node->next_index;

            /* Link to error list */
            current_node->next_index = error_list_header->next_index;
            error_list_header->next_index = current_node - proc_table;
        }
        else
            previous_node = current_node;

        current_node = next_node;
    }
    proctable_pm_unlock(main_server);
}

static apr_time_t lastbusyscan = 0;
static void scan_busylist(server_rec * main_server)
{
    fcgid_procnode *current_node;
    fcgid_procnode *proc_table;
    apr_time_t last_active_time;
    apr_time_t now = apr_time_now();
    fcgid_server_conf *sconf =
        ap_get_module_config(main_server->module_config,
                             &fcgid_module);

    /* Should I check the busy list? */
    if (procmgr_must_exit()
        || apr_time_sec(now) - apr_time_sec(lastbusyscan) <=
        sconf->busy_scan_interval)
        return;
    lastbusyscan = now;

    /* Check busy list */
    proc_table = proctable_get_table_array();

    proctable_pm_lock(main_server);
    current_node = &proc_table[proctable_get_busy_list()->next_index];
    while (current_node != proc_table) {
        last_active_time = current_node->last_active_time;
        if (apr_time_sec(now) - apr_time_sec(last_active_time) >
            (current_node->cmdopts.busy_timeout)) {
            /* Protocol: 
               1. diewhy init with FCGID_DIE_KILLSELF
               2. Process manager set diewhy to FCGID_DIE_BUSY_TIMEOUT and gracefully kill process while busy timeout
               3. Process manager forced kill process while busy timeout and diewhy is FCGID_DIE_BUSY_TIMEOUT
             */
            if (current_node->diewhy == FCGID_DIE_BUSY_TIMEOUT)
                proc_kill_force(current_node, main_server);
            else {
                current_node->diewhy = FCGID_DIE_BUSY_TIMEOUT;
                proc_kill_gracefully(current_node, main_server);
            }
        }
        current_node = &proc_table[current_node->next_index];
    }
    proctable_pm_unlock(main_server);
}

static apr_time_t lastzombiescan = 0;
static void scan_idlelist_zombie(server_rec * main_server)
{
    /* 
       Scan the idle list 
       1. pick up the node for scan(now-last_activ>g_zombie_scan_interval)
       2. check if it's zombie process
       3. if it's zombie process, wait() and return to free list
       4. return to idle list if it's not zombie process
     */
    pid_t thepid;
    fcgid_procnode *previous_node, *current_node, *next_node;
    fcgid_procnode *check_list_header;
    fcgid_procnode *proc_table;
    apr_time_t last_active_time;
    apr_time_t now = apr_time_now();
    fcgid_procnode temp_header;
    fcgid_server_conf *sconf =
        ap_get_module_config(main_server->module_config,
                             &fcgid_module);

    memset(&temp_header, 0, sizeof(temp_header));

    /* Should I check zombie processes in idle list now? */
    if (procmgr_must_exit()
        || apr_time_sec(now) - apr_time_sec(lastzombiescan) <=
        sconf->zombie_scan_interval)
        return;
    lastzombiescan = now;

    /* 
       Check the list 
     */
    proc_table = proctable_get_table_array();
    previous_node = proctable_get_idle_list();
    check_list_header = &temp_header;

    proctable_pm_lock(main_server);
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];

        /* Is it time for zombie check? */
        last_active_time = current_node->last_active_time;
        if (apr_time_sec(now) - apr_time_sec(last_active_time) >
            sconf->zombie_scan_interval) {
            /* Unlink from idle list */
            previous_node->next_index = current_node->next_index;

            /* Link to check list */
            current_node->next_index = check_list_header->next_index;
            check_list_header->next_index = current_node - proc_table;
        }
        else
            previous_node = current_node;

        current_node = next_node;
    }
    proctable_pm_unlock(main_server);

    /* 
       Now check every node in check list
       1) If it's zombie process, wait() and return to free list
       2) If it's not zombie process, link it to the tail of idle list
     */
    previous_node = check_list_header;
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];

        /* Is it zombie process? */
        thepid = current_node->proc_id.pid;
        if (proc_wait_process(main_server, current_node) == APR_CHILD_DONE) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                         "mod_fcgid: cleanup zombie process %"
                         APR_PID_T_FMT, thepid);

            /* Unlink from check list */
            previous_node->next_index = current_node->next_index;

            /* Link to free list */
            link_node_to_list(main_server, proctable_get_free_list(),
                              current_node, proc_table);
        }
        else
            previous_node = current_node;

        current_node = next_node;
    }

    /* 
       Now link the check list back to the tail of idle list 
     */
    if (check_list_header->next_index) {
        proctable_pm_lock(main_server);
        previous_node = proctable_get_idle_list();
        current_node = &proc_table[previous_node->next_index];

        /* Find the tail of idle list */
        while (current_node != proc_table) {
            previous_node = current_node;
            current_node = &proc_table[current_node->next_index];
        }

        /* Link check list to the tail of idle list */
        previous_node->next_index = check_list_header->next_index;
        proctable_pm_unlock(main_server);
    }
}

static apr_time_t lasterrorscan = 0;
static void scan_errorlist(server_rec * main_server)
{
    /* 
       kill() and wait() every node in error list
       put them back to free list after that
     */
    void *dummy;
    fcgid_procnode *previous_node, *current_node, *next_node;
    apr_time_t now = apr_time_now();
    fcgid_procnode *error_list_header = proctable_get_error_list();
    fcgid_procnode *free_list_header = proctable_get_free_list();
    fcgid_procnode *proc_table = proctable_get_table_array();
    fcgid_procnode temp_error_header;
    fcgid_server_conf *sconf =
        ap_get_module_config(main_server->module_config,
                             &fcgid_module);
    int graceful_terminations = 0;

    /* Should I check the busy list? */
    if (procmgr_must_exit()
        || apr_time_sec(now) - apr_time_sec(lasterrorscan) <=
        sconf->error_scan_interval)
        return;
    lasterrorscan = now;

    /* Try wait dead processes, restore to free list */
    /* Note: I can't keep the lock during the scan */
    proctable_pm_lock(main_server);
    temp_error_header.next_index = error_list_header->next_index;
    error_list_header->next_index = 0;
    proctable_pm_unlock(main_server);

    previous_node = &temp_error_header;
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];

        if (proc_wait_process(main_server, current_node) != APR_CHILD_NOTDONE) {
            /* Unlink from error list */
            previous_node->next_index = current_node->next_index;

            /* Link to free list */
            current_node->next_index = free_list_header->next_index;
            free_list_header->next_index = current_node - proc_table;
        }
        else
            previous_node = current_node;

        current_node = next_node;
    }

    /* Kill the left processes, wait() them in the next round */
    for (current_node = &proc_table[temp_error_header.next_index];
         current_node != proc_table;
         current_node = &proc_table[current_node->next_index]) {
        /* Try gracefully first */
        dummy = NULL;
        apr_pool_userdata_get(&dummy, HAS_GRACEFUL_KILL,
                              current_node->proc_pool);
        if (!dummy) {
            proc_kill_gracefully(current_node, main_server);
            ++graceful_terminations;
            apr_pool_userdata_set("set", HAS_GRACEFUL_KILL,
                                  apr_pool_cleanup_null,
                                  current_node->proc_pool);
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                         "mod_fcgid: process %" APR_PID_T_FMT
                         " graceful kill fail, sending SIGKILL",
                         current_node->proc_id.pid);
            proc_kill_force(current_node, main_server);
        }
    }

    /* Link the temp error list back */
    proctable_pm_lock(main_server);
    /* Find the tail of error list */
    previous_node = error_list_header;
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        previous_node = current_node;
        current_node = &proc_table[current_node->next_index];
    }
    previous_node->next_index = temp_error_header.next_index;
    proctable_pm_unlock(main_server);

    if (graceful_terminations) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server,
                     "mod_fcgid: gracefully terminated %d processes",
                     graceful_terminations);
    }
}

typedef enum action_t {DO_NOTHING, KILL_GRACEFULLY, KILL_FORCEFULLY,
                       HARD_WAIT} action_t;

static int reclaim_one_pid(server_rec *main_server, fcgid_procnode *proc,
                           action_t action)
{
    int exitcode;
    apr_exit_why_e exitwhy;
    apr_wait_how_e wait_how = action == HARD_WAIT ? APR_WAIT : APR_NOWAIT;

    if (apr_proc_wait(&proc->proc_id, &exitcode, &exitwhy,
                      wait_how) != APR_CHILD_NOTDONE) {
        proc->diewhy = FCGID_DIE_SHUTDOWN;
        proc_print_exit_info(proc, exitcode, exitwhy,
                             main_server);
        apr_pool_destroy(proc->proc_pool);
        proc->proc_pool = NULL;
        return 1;
    }

    switch(action) {
    case DO_NOTHING:
    case HARD_WAIT:
        break;

    case KILL_GRACEFULLY:
        proc_kill_gracefully(proc, main_server);
        break;

    case KILL_FORCEFULLY:
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server,
                     "FastCGI process %" APR_PID_T_FMT
                     " still did not exit, "
                     "terminating forcefully",
                     proc->proc_id.pid);
        proc_kill_force(proc, main_server);
        break;
    }

    return 0;
}

static void kill_all_subprocess(server_rec *main_server)
{
    apr_time_t waittime = 1024 * 16;
    size_t i, table_size = proctable_get_table_size();
    int not_dead_yet;
    int cur_action, next_action;
    apr_time_t starttime = apr_time_now();
    struct {
        action_t action;
        apr_time_t action_time;
    } action_table[] = {
        {DO_NOTHING,      0}, /* dummy entry for iterations where
                              * we reap children but take no action
                              * against stragglers
                              */
        {KILL_GRACEFULLY, apr_time_from_sec(0)},
        {KILL_GRACEFULLY, apr_time_from_sec(1)},
        {KILL_FORCEFULLY, apr_time_from_sec(8)},
        {HARD_WAIT,       apr_time_from_sec(8)}
    };
    fcgid_procnode *proc_table = proctable_get_table_array();

    next_action = 1;
    do {
        apr_sleep(waittime);
        /* don't let waittime get longer than 1 second; otherwise, we don't
         * react quickly to the last child exiting, and taking action can
         * be delayed
         */
        waittime = waittime * 4;
        if (waittime > apr_time_from_sec(1)) {
            waittime = apr_time_from_sec(1);
        }

        /* see what action to take, if any */
        if (action_table[next_action].action_time <= apr_time_now() - starttime) {
            cur_action = next_action;
            ++next_action;
        }
        else {
            cur_action = 0; /* index of DO_NOTHING entry */
        }

        /* now see who is done */
        not_dead_yet = 0;
        for (i = 0; i < table_size; i++) {
            if (!proc_table[i].proc_pool) {
                continue; /* unused */
            }

            if (!reclaim_one_pid(main_server, &proc_table[i],
                                 action_table[cur_action].action)) {
                ++not_dead_yet;
            }
        }
        
    } while (not_dead_yet &&
             action_table[cur_action].action != HARD_WAIT);
}

/* This should be proposed as a stand-alone improvement to the httpd module,
 * either in the arch/ platform-specific modules or util_script.c from whence
 * it came.
 */
static void default_proc_env(apr_table_t * e)
{
    const char *env_temp;

    if (!(env_temp = getenv("PATH"))) {
        env_temp = DEFAULT_PATH;
    }
    apr_table_addn(e, "PATH", env_temp);

#ifdef WIN32
    if ((env_temp = getenv("SYSTEMROOT"))) {
        apr_table_addn(e, "SYSTEMROOT", env_temp);
    }
    if ((env_temp = getenv("COMSPEC"))) {
        apr_table_addn(e, "COMSPEC", env_temp);
    }
    if ((env_temp = getenv("PATHEXT"))) {
        apr_table_addn(e, "PATHEXT", env_temp);
    }
    if ((env_temp = getenv("WINDIR"))) {
        apr_table_addn(e, "WINDIR", env_temp);
    }
#elif defined(OS2)
    if ((env_temp = getenv("COMSPEC")) != NULL) {
        apr_table_addn(e, "COMSPEC", env_temp);
    }
    if ((env_temp = getenv("ETC")) != NULL) {
        apr_table_addn(e, "ETC", env_temp);
    }
    if ((env_temp = getenv("DPATH")) != NULL) {
        apr_table_addn(e, "DPATH", env_temp);
    }
    if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) {
        apr_table_addn(e, "PERLLIB_PREFIX", env_temp);
    }
#elif defined(BEOS)
    if ((env_temp = getenv("LIBRARY_PATH")) != NULL) {
        apr_table_addn(e, "LIBRARY_PATH", env_temp);
    }
#elif defined (AIX)
    if ((env_temp = getenv("LIBPATH"))) {
        apr_table_addn(e, "LIBPATH", env_temp);
    }
#else
/* DARWIN, HPUX vary depending on circumstance */
#if defined (DARWIN)
    if ((env_temp = getenv("DYLD_LIBRARY_PATH"))) {
        apr_table_addn(e, "DYLD_LIBRARY_PATH", env_temp);
    }
#elif defined (HPUX11) || defined (HPUX10) || defined (HPUX)
    if ((env_temp = getenv("SHLIB_PATH"))) {
        apr_table_addn(e, "SHLIB_PATH", env_temp);
    }
#endif
    if ((env_temp = getenv("LD_LIBRARY_PATH"))) {
        apr_table_addn(e, "LD_LIBRARY_PATH", env_temp);
    }
#endif
}

/* End of common to util_script.c */

static void
fastcgi_spawn(fcgid_command * command, server_rec * main_server,
              apr_pool_t * configpool)
{
    fcgid_procnode *free_list_header, *proctable_array,
        *procnode, *idle_list_header;
    fcgid_proc_info procinfo;
    apr_status_t rv;
    int i;

    free_list_header = proctable_get_free_list();
    idle_list_header = proctable_get_idle_list();
    proctable_array = proctable_get_table_array();

    /* Apply a slot from free list */
    proctable_pm_lock(main_server);
    if (free_list_header->next_index == 0) {
        proctable_pm_unlock(main_server);
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                     "mod_fcgid: too much processes, please increase FCGID_MAX_APPLICATION");
        return;
    }
    procnode = &proctable_array[free_list_header->next_index];
    free_list_header->next_index = procnode->next_index;
    procnode->next_index = 0;
    proctable_pm_unlock(main_server);

    /* Prepare to spawn */
    procnode->deviceid = command->deviceid;
    procnode->inode = command->inode;

    /* no truncation should ever occur */
    AP_DEBUG_ASSERT(sizeof procnode->cmdline > strlen(command->cmdline));
    apr_cpystrn(procnode->cmdline, command->cmdline, sizeof procnode->cmdline);

    procnode->vhost_id = command->vhost_id;
    procnode->uid = command->uid;
    procnode->gid = command->gid;
    procnode->start_time = procnode->last_active_time = apr_time_now();
    procnode->requests_handled = 0;
    procnode->diewhy = FCGID_DIE_KILLSELF;
    procnode->proc_pool = NULL;
    procnode->cmdopts = command->cmdopts;

    procinfo.cgipath = command->cgipath;
    procinfo.configpool = configpool;
    procinfo.main_server = main_server;
    procinfo.uid = command->uid;
    procinfo.gid = command->gid;
    procinfo.userdir = command->userdir;
    if ((rv =
         apr_pool_create(&procnode->proc_pool, configpool)) != APR_SUCCESS
        || (procinfo.proc_environ =
            apr_table_make(procnode->proc_pool, INITENV_CNT)) == NULL) {
        /* Link the node back to free list in this case */
        if (procnode->proc_pool)
            apr_pool_destroy(procnode->proc_pool);
        link_node_to_list(main_server, free_list_header, procnode,
                          proctable_array);

        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, main_server,
                     "mod_fcgid: can't create pool for process");
        return;
    }
    /* Set up longer, system defaults before falling into parsing fixed-limit
     * request-by-request variables, so if any are overriden, they preempt
     * any system default assumptions
     */
    default_proc_env(procinfo.proc_environ);
    for (i = 0; i < INITENV_CNT; i++) {
        if (command->cmdenv.initenv_key[i][0] == '\0')
            break;
        apr_table_set(procinfo.proc_environ, command->cmdenv.initenv_key[i],
                      command->cmdenv.initenv_val[i]);
    }

    /* Spawn the process now */
    /* XXX Spawn uses wrapper_cmdline, but log uses cgipath ? */
    if ((rv =
         proc_spawn_process(command->cmdline, &procinfo,
                            procnode)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, main_server,
                     "mod_fcgid: spawn process %s error", command->cgipath);

        apr_pool_destroy(procnode->proc_pool);
        link_node_to_list(main_server, free_list_header,
                          procnode, proctable_array);
        return;
    }
    else {
        /* The job done */
        link_node_to_list(main_server, idle_list_header,
                          procnode, proctable_array);
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
                     "mod_fcgid: server %s:%s(%" APR_PID_T_FMT ") started",
                     command->server_hostname[0] ?
                         command->server_hostname : "(unknown)",
                     command->cgipath,
                     procnode->proc_id.pid);
        register_spawn(main_server, procnode);
    }
}

apr_status_t pm_main(server_rec * main_server, apr_pool_t * configpool)
{
    fcgid_command command;

    while (1) {
        if (procmgr_must_exit())
            break;

        /* Wait for command */
        if (procmgr_peek_cmd(&command, main_server) == APR_SUCCESS) {
            if (is_spawn_allowed(main_server, &command))
                fastcgi_spawn(&command, main_server, configpool);

            procmgr_finish_notify(main_server);
        }

        /* Move matched node to error list */
        scan_idlelist_zombie(main_server);
        scan_idlelist(main_server);
        scan_busylist(main_server);

        /* Kill() and wait() nodes in error list */
        scan_errorlist(main_server);
    }

    /* Stop all processes */
    kill_all_subprocess(main_server);

    return APR_SUCCESS;
}
