/*
 * 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.
 */

#include "apr_thread_proc.h"
#include "apr_strings.h"
#include "apr_queue.h"
#include "fcgid_pm.h"
#include "fcgid_pm_main.h"
#include "fcgid_conf.h"
#include "fcgid_spawn_ctl.h"
#define FCGID_MSGQUEUE_SIZE 10

static apr_thread_t *g_thread = NULL;
static apr_queue_t *g_msgqueue = NULL;
static apr_queue_t *g_notifyqueue = NULL;
static apr_thread_mutex_t *g_reqlock = NULL;
static apr_thread_t *g_wakeup_thread = NULL;
static int g_must_exit = 0;
static int g_wakeup_timeout = 0;

static void *APR_THREAD_FUNC wakeup_thread(apr_thread_t * thd, void *data)
{
    while (!g_must_exit) {
        /* Wake up every second to check g_must_exit flag */
        int i;

        for (i = 0; i < g_wakeup_timeout; i++) {
            if (g_must_exit)
                break;
            apr_sleep(apr_time_from_sec(1));
        }

        /* Send a wake up message to procmgr_fetch_cmd() */
        if (!g_must_exit && g_msgqueue)
            apr_queue_trypush(g_msgqueue, NULL);
    }
    return NULL;
}

static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *data)
{
    server_rec *main_server = data;

    pm_main(main_server, main_server->process->pconf);
    return NULL;
}

apr_status_t procmgr_pre_config(apr_pool_t *p, apr_pool_t *plog,
                                apr_pool_t *ptemp)
{
    return APR_SUCCESS;
}

apr_status_t
procmgr_post_config(server_rec * main_server, apr_pool_t * pconf)
{
    apr_status_t rv;
    fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config,
                                                    &fcgid_module);

    /* Initialize spawn controler */
    spawn_control_init(main_server, pconf);

    /* Create a message queues */
    if ((rv = apr_queue_create(&g_msgqueue, FCGID_MSGQUEUE_SIZE,
                               pconf)) != APR_SUCCESS
        || (rv = apr_queue_create(&g_notifyqueue, FCGID_MSGQUEUE_SIZE,
                                  pconf)) != APR_SUCCESS) {
        /* Fatal error */
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: can't create message queue");
        exit(1);
    }

    /* Create request lock */
    if ((rv = apr_thread_mutex_create(&g_reqlock,
                                      APR_THREAD_MUTEX_DEFAULT,
                                      pconf)) != APR_SUCCESS) {
        /* Fatal error */
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: Can't create request mutex");
        exit(1);
    }

    /* Calculate procmgr_fetch_cmd wake up interval */
    g_wakeup_timeout = min(sconf->error_scan_interval,
                           sconf->busy_scan_interval);
    g_wakeup_timeout = min(sconf->idle_scan_interval,
                           g_wakeup_timeout);
    if (g_wakeup_timeout == 0)
        g_wakeup_timeout = 1;   /* Make it reasonable */

    /* Create process manager worker thread */
    if ((rv = apr_thread_create(&g_thread, NULL, worker_thread,
                                main_server, pconf)) != APR_SUCCESS) {
        /* It's a fatal error */
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: can't create process manager thread");
        exit(1);
    }

    /* Create wake up thread */
    /* XXX If there was a function such like apr_queue_pop_timedwait(),
       then I don't need such an ugly thread to do the wake up job */
    if ((rv = apr_thread_create(&g_wakeup_thread, NULL, wakeup_thread,
                                NULL, pconf)) != APR_SUCCESS) {
        /* It's a fatal error */
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: can't create wake up thread");
        exit(1);
    }

    apr_pool_cleanup_register(pconf, main_server, procmgr_stop_procmgr,
                              apr_pool_cleanup_null);

    return APR_SUCCESS;
}

void procmgr_init_spawn_cmd(fcgid_command * command, request_rec * r,
                            fcgid_cmd_conf *cmd_conf)
{
    fcgid_server_conf *sconf =
        ap_get_module_config(r->server->module_config, &fcgid_module);

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

    command->uid = (uid_t) - 1;
    command->gid = (gid_t) - 1;
    command->userdir = 0;
    command->vhost_id = sconf->vhost_id;
    if (r->server->server_hostname) {
        apr_cpystrn(command->server_hostname, r->server->server_hostname,
                    sizeof command->server_hostname);
    }

    get_cmd_options(r, command->cgipath, &command->cmdopts, &command->cmdenv);
}

apr_status_t procmgr_send_spawn_cmd(fcgid_command * command,
                                    request_rec * r)
{
     char *notifybyte = NULL;
    if (g_thread && g_msgqueue && !g_must_exit
        && g_reqlock && g_notifyqueue) {
        apr_status_t rv;

        /*
           Prepare the message send to another thread
           destroy the message if I can't push to message
         */
        fcgid_command *postcmd =
            (fcgid_command *) malloc(sizeof(fcgid_command));
        if (!postcmd)
            return APR_ENOMEM;
        memcpy(postcmd, command, sizeof(*command));

        /* Get request lock first */
        if ((rv = apr_thread_mutex_lock(g_reqlock)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r,
                          "mod_fcgid: can't get request lock");
            return rv;
        }

        /* Try push the message */
        if ((rv = apr_queue_push(g_msgqueue, postcmd)) != APR_SUCCESS) {
            apr_thread_mutex_unlock(g_reqlock);
            free(postcmd);
            ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r,
                          "mod_fcgid: can't push request message");
            return rv;
        } else {
            /* Wait the respond from process manager */
            if ((rv =
                 apr_queue_pop(g_notifyqueue,
                               (void **)&notifybyte)) != APR_SUCCESS) {
                apr_thread_mutex_unlock(g_reqlock);
                ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r,
                              "mod_fcgid: can't pop notify message");
                return rv;
            }
        }

        /* Release the lock now */
        if ((rv = apr_thread_mutex_unlock(g_reqlock)) != APR_SUCCESS) {
            /* It's a fatal error */
            ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r,
                          "mod_fcgid: can't release request lock");
            exit(1);
        }
    }

    if( notifybyte && *notifybyte==PROCMGR_PROC_CREATED )
        return APR_SUCCESS;
    else
        return APR_CHILD_NOTDONE;
}

static char g_proc_created = PROCMGR_PROC_CREATED;
static char g_proc_not_created = PROCMGR_PROC_NOT_CREATED;
apr_status_t procmgr_finish_notify(server_rec * main_server, char proc_created)
{
    apr_status_t rv;
    char *notify = NULL;
    if( proc_created==PROCMGR_PROC_CREATED )
        notify = &g_proc_created;
    else
        notify = &g_proc_not_created;

    if ((rv = apr_queue_push(g_notifyqueue, notify)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: can't send spawn notify");
    }

    return rv;
}

apr_status_t procmgr_fetch_cmd(fcgid_command * command,
                              server_rec * main_server)
{
    fcgid_command *peakcmd = NULL;

    if (!g_must_exit && g_msgqueue) {
        if (apr_queue_pop(g_msgqueue, (void **)&peakcmd) == APR_SUCCESS) {
            if (!peakcmd)
                return APR_TIMEUP;  /* This a wake up message */
            else {
                /* Copy the command, and then free the memory */
                memcpy(command, peakcmd, sizeof(*peakcmd));
                free(peakcmd);

                return APR_SUCCESS;
            }
        }
    }

    return APR_TIMEUP;
}

apr_status_t
procmgr_child_init(server_rec * main_server, apr_pool_t * pchild)
{
    /* Noop on windows, but used by unix */

    return APR_SUCCESS;
}

int procmgr_must_exit()
{
    return g_must_exit;
}

apr_status_t procmgr_stop_procmgr(void *server)
{
    apr_status_t status;
    fcgid_server_conf *conf;

    /* Tell the world to die */
    g_must_exit = 1;
    if (g_msgqueue)
        apr_queue_push(g_msgqueue, NULL);

    /* Wait */
    if (g_thread && apr_thread_join(&status, g_thread) == APR_SUCCESS) {
        /* Free the memory left in queue */
        fcgid_command *peakcmd = NULL;

        while (apr_queue_trypop(g_msgqueue, (void **)&peakcmd) == APR_SUCCESS) {
            if (peakcmd)
                free(peakcmd);
        }
    }

    /* Clean up the Job object if present */
    conf = ap_get_module_config(((server_rec*)server)->module_config,
                                &fcgid_module);

    if (conf->hJobObjectForAutoCleanup != NULL) {
        CloseHandle(conf->hJobObjectForAutoCleanup);
    }

    if (g_wakeup_thread)
        return apr_thread_join(&status, g_wakeup_thread);

    return APR_SUCCESS;
}
