/* mod_rivet.c -- The apache module itself, for Apache 2.4. */

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

/* Rivet config */
#ifdef HAVE_CONFIG_H
#include <rivet_config.h>
#endif

/* Apache includes */
#include <httpd.h>
#include <http_config.h>
#include <http_core.h>
#include <http_protocol.h>
#include <http_log.h>
#include <http_main.h>
#include <ap_config.h>
#include <ap_mpm.h>
#include <apr_strings.h>
#include <apr_general.h>
#include <apr_time.h>
#include <apr_thread_proc.h>
#include <apr_thread_cond.h>
#include <apr_file_io.h>
#include <apr_file_info.h>
#include <apr_env.h>

/* Tcl includes */
#include <tcl.h>

/* as long as we need to emulate ap_chdir_file we need to include unistd.h */
#ifdef RIVET_HAVE_UNISTD_H
#include <unistd.h>
#endif /* RIVET_HAVE_UNISTD_H */

#include "rivet_types.h"
#include "mod_rivet.h"
#include "apache_config.h"

/* Function prototypes are defined with EXTERN. Since we are in the same DLL,
 * no need to keep this extern... */
#ifdef EXTERN
#   undef EXTERN
#   define EXTERN
#endif /* EXTERN */
#include "rivet.h"
#include "mod_rivet_common.h"
#include "mod_rivet_generator.h"

module AP_MODULE_DECLARE_DATA rivet_module;
extern Tcl_ChannelType        RivetChan;
DLLEXPORT apr_threadkey_t*    rivet_thread_key    = NULL;
DLLEXPORT mod_rivet_globals*  module_globals      = NULL;

#define ERRORBUF_SZ         256
#define TCL_HANDLER_FILE    RIVET_DIR"/default_request_handler.tcl"

/*
 * -- Rivet_SeekMPMBridge
 *
 * MPM name determination. The function returns a filename to 
 * an MPM bridge module. The module name is determined in 4 steps
 *
 *  - The environment variable RIVET_MPM_BRIDGE is checked. I the
 *    variable exists its value is returned as the path to the bridge module
 *    If the module doesn't exist the server exits with an error
 *  - The global configuration is checked. If module_globals->mpm_bridge is
 *    not NULL its value is taken as the bridge name as given by means of 
 *    the server configuration directive RivetMpmBridge. 
 *    The value is interpolated with the macro RIVET_MPM_BRIDGE_COMPOSE
 *    to compose the full path (e.g. 'lazy' -> RIVET_DIR'/mpm/rivet_lazy_mpm.so')
 *    to the bridge module. 
 *  - If the interpolated file name doesn't exist the mpm_bridge string is
 *    checked as a full path to the MPM bridge. If not existing the server exits
 *  - An heuristics criterion based on the MPM module features returned by
 *    mpm_bridge_query is evaluated.
 *
 */

static char*
Rivet_SeekMPMBridge (apr_pool_t* pool)
{
    char*           mpm_bridge_path;
    int             ap_mpm_result;
    apr_status_t    apr_ret;
    apr_finfo_t     finfo;

    /* With the env variable RIVET_MPM_BRIDGE we have the chance to tell mod_rivet 
       what bridge custom implementation we want be loaded */

    if (apr_env_get (&mpm_bridge_path,"RIVET_MPM_BRIDGE",pool) == APR_SUCCESS)
    {
        if ((apr_ret = apr_stat(&finfo,mpm_bridge_path,APR_FINFO_MIN,pool)) != APR_SUCCESS)
        {
            ap_log_perror(APLOG_MARK,APLOG_ERR,apr_ret,pool, 
                          MODNAME ": MPM bridge %s not found", module_globals->mpm_bridge); 
            exit(1);   
        }
        return mpm_bridge_path;
    }

    /* we now look into the configuration record */

    if (module_globals->mpm_bridge != NULL)
    {
        char* proposed_bridge;

        proposed_bridge = apr_pstrcat(pool,RIVET_DIR,RIVET_MPM_BRIDGE_COMPOSE(module_globals->mpm_bridge),NULL);
        if (apr_stat(&finfo,proposed_bridge,APR_FINFO_MIN,pool) == APR_SUCCESS)
        {
            mpm_bridge_path = proposed_bridge;
        }
        else if ((apr_ret = apr_stat(&finfo,module_globals->mpm_bridge,APR_FINFO_MIN,pool)) == APR_SUCCESS)
        {
            mpm_bridge_path = apr_pstrdup(pool,module_globals->mpm_bridge);
        }
        else
        {
            ap_log_perror(APLOG_MARK,APLOG_ERR,apr_ret,pool,
                                     MODNAME ": MPM bridge %s (%s) not found",module_globals->mpm_bridge,
                                                                              proposed_bridge); 
            exit(1);   
        }

    } else {

        /* MPM bridge determination heuristics */

        /* Let's query the Apache server about the current MPM threaded capabilities */

        if (ap_mpm_query(AP_MPMQ_IS_THREADED,&ap_mpm_result) == APR_SUCCESS)
        {
            if (ap_mpm_result == AP_MPMQ_NOT_SUPPORTED)
            {
                /* Since the MPM is not threaded we assume we can load the prefork bridge */

                mpm_bridge_path = apr_pstrcat(pool,RIVET_MPM_BRIDGE_COMPOSE("prefork"),NULL);
            }
            else
            {
                mpm_bridge_path = apr_pstrcat(pool,RIVET_MPM_BRIDGE_COMPOSE("worker"),NULL);
            }
        }
        else
        {

            /* Execution shouldn't get here as a failure querying about MPM is supposed
             * to return APR_SUCCESS in every normal operative conditions. We
             * give a default to the MPM bridge anyway
             */

            mpm_bridge_path = apr_pstrcat(pool,RIVET_MPM_BRIDGE_COMPOSE("worker"),NULL);
        }
        mpm_bridge_path = apr_pstrcat(pool,RIVET_DIR,mpm_bridge_path,NULL);

    }
    return mpm_bridge_path;
}

/*
 * -- Rivet_CreateModuleGlobals
 *
 * module globals (mod_rivet_globals) allocation and initialization.
 * As of 3.2 the procedure initialized the fields that can be set
 * during the pre_config stage of the server initialization
 *
 */

static mod_rivet_globals* 
Rivet_CreateModuleGlobals (apr_pool_t* pool)
{
    mod_rivet_globals*  mod_rivet_g;
   
    mod_rivet_g = apr_pcalloc(pool,sizeof(mod_rivet_globals));
    mod_rivet_g->single_thread_exit       = SINGLE_THREAD_EXIT_UNDEF;
    mod_rivet_g->separate_virtual_interps = RIVET_SEPARATE_VIRTUAL_INTERPS;
    mod_rivet_g->separate_channels        = RIVET_SEPARATE_CHANNELS;
    if (apr_pool_create(&mod_rivet_g->pool, NULL) != APR_SUCCESS) 
    {
        ap_log_perror(APLOG_MARK,APLOG_ERR,APR_EGENERAL,pool,
                      MODNAME ": could not initialize rivet module global pool");
        exit(1);
    }

    /* read the default request handler code */

    if (Rivet_ReadFile(pool,TCL_HANDLER_FILE,
                            &mod_rivet_g->default_handler,
                            &mod_rivet_g->default_handler_size) > 0)
    {
        ap_log_perror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, pool, 
                     MODNAME ": could not read rivet default handler");
        exit(1);
    }

    return mod_rivet_g;
}

/*
 * -- Rivet_Exit_Handler
 *
 * 
 *
 */

int Rivet_Exit_Handler(int code)
{
    //Tcl_Exit(code);
    /*NOTREACHED*/
    return TCL_OK;		/* Better not ever reach this! */
}

/* 
 * -- Rivet_RunServerInit
 *
 *  Prepare the execution of any Rivet server initialization script
 *
 */

static int
Rivet_RunServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server_rec *s)
{
#ifdef WIN32
	char*	parent_pid_var = NULL;
#endif

    FILEDEBUGINFO;

    /* we create and initialize a master (server) interpreter */

    module_globals->server_interp = Rivet_NewVHostInterp(pPool,0); /* root interpreter */

    /* We initialize the interpreter and we won't register a channel with it because
     * we couldn't send data to the stdout anyway 
	 */

    Rivet_PerInterpInit(module_globals->server_interp,NULL,s,pPool);

	/* This code conditionally compiled when we are building for the
	 * Windows family of OS. The winnt MPM runs the post_config 
	 * hooks after it has spawned a child process but we don't want
	 * to run the Tcl server initialization script again. We
	 * detect we are in a child process by checking
	 * the environment variable AP_PARENT_PID 
	 * (https://wiki.apache.org/httpd/ModuleLife)
	 */
	
	#ifdef WIN32
	
	/* if the environment variable AP_PARENT_PID is set 
     * we know we are in a child process of the winnt MPM
     */
	
	apr_env_get(&parent_pid_var,"AP_PARENT_PID",pTemp);
	if (parent_pid_var != NULL)
	{
		ap_log_perror(APLOG_MARK,APLOG_INFO,0,pPool,
				"AP_PARENT_PID found: not running the Tcl server script in winnt MPM child process");
		return OK;
	} else {
		ap_log_perror(APLOG_MARK,APLOG_INFO,0,pPool,
				 "AP_PARENT_PID undefined, we proceed with server initialization");
	}
	
	#endif
	
    /* We don't create the cache here: it would make sense for prefork MPM
     * but threaded MPM bridges have their pool of threads. Each of them
     * will by now have their own cache
     */

    if (module_globals->rivet_server_init_script != NULL) {
        Tcl_Interp* interp      = module_globals->server_interp->interp;
        Tcl_Obj*    server_init = Tcl_NewStringObj(module_globals->rivet_server_init_script,-1);

        Tcl_IncrRefCount(server_init);

        if (Tcl_EvalObjEx(interp, server_init, 0) != TCL_OK)
        {
            ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s, 
                         MODNAME ": Error running ServerInitScript '%s': %s",
                         module_globals->rivet_server_init_script,
                         Tcl_GetVar(interp, "errorInfo", 0));
        } else {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, s,
                         MODNAME ": ServerInitScript '%s' successful", 
                         module_globals->rivet_server_init_script);
        }

        Tcl_DecrRefCount(server_init);
    }

	/* bridge specific server init script */
	
	RIVET_MPM_BRIDGE_CALL(server_init,pPool,pLog,pTemp,s);

    return OK;
}

/* -- Rivet_ServerInit
 *
 * Post config hook. The server initialization loads the MPM bridge
 * and runs the Tcl server initialization script
 *
 */

static int
Rivet_ServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server_rec *server)
{
    apr_dso_handle_t*   dso_handle;
	void*				userdata;
	const char 			*userdata_key = "rivet_post_config";

#if RIVET_DISPLAY_VERSION
    ap_add_version_component(pPool,RIVET_PACKAGE_NAME"/"RIVET_VERSION);
#else
    ap_add_version_component(pPool,RIVET_PACKAGE_NAME);
#endif

	/* This function runs as post_config_hook
	 * and as such it's run twice by design. 
	 * This is the recommended way to avoid a double load of
	 * external modules.
	 */

	apr_pool_userdata_get(&userdata, userdata_key, server->process->pool);
	if (userdata == NULL)
	{
		apr_pool_userdata_set((const void *)1, userdata_key,
                              apr_pool_cleanup_null, server->process->pool);

        ap_log_error(APLOG_MARK,APLOG_DEBUG,0,server,
                     "first post_config run: not initializing Tcl stuff");

        return OK; /* This would be the first time through */
	}
	
    /* Everything revolves around this structure: module_globals */

    /* the module global structure is allocated and the MPM bridge name established */

    // module_globals = Rivet_CreateModuleGlobals (pPool,server);

    /* We can proceed initializing the globals with information stored in the module configuration */

    module_globals->rivet_mpm_bridge = Rivet_SeekMPMBridge(pPool);
    module_globals->server           = server;

    /* The bridge is loaded and the jump table sought */

    if (apr_dso_load(&dso_handle,module_globals->rivet_mpm_bridge,pPool) == APR_SUCCESS)
    {
        apr_status_t            rv;
        apr_dso_handle_sym_t    bjt = NULL;

        ap_log_perror(APLOG_MARK,APLOG_DEBUG,APR_EGENERAL,pTemp,
                     "MPM bridge loaded: %s",module_globals->rivet_mpm_bridge);

        rv = apr_dso_sym(&bjt,dso_handle,"bridge_jump_table");
        if (rv == APR_SUCCESS)
        {
            module_globals->bridge_jump_table = (rivet_bridge_table*) bjt;
        }
        else
        {
            char errorbuf[ERRORBUF_SZ];

            ap_log_error (APLOG_MARK, APLOG_ERR, APR_EGENERAL, server, 
                          MODNAME ": Error loading symbol bridge_jump_table: %s", 
                          apr_dso_error(dso_handle,errorbuf,ERRORBUF_SZ));
            exit(1);   
        }

        /* we require only request_processor and thread_interp to be defined */

        ap_assert(RIVET_MPM_BRIDGE_FUNCTION(request_processor) != NULL);
        ap_assert(RIVET_MPM_BRIDGE_FUNCTION(thread_interp) != NULL);

        apr_thread_mutex_create(&module_globals->pool_mutex, APR_THREAD_MUTEX_UNNESTED, pPool);

    }
    else
    {
        char errorbuf[ERRORBUF_SZ];

        /* If we can't load the mpm handler module we give up and exit */

        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server, 
                     MODNAME " Error loading MPM manager: %s", 
                     apr_dso_error(dso_handle,errorbuf,ERRORBUF_SZ));
        exit(1);
    }

    Rivet_RunServerInit(pPool,pLog,pTemp,server);

    return OK;
}

/*
 * -- Rivet_Finalize
 *
 */

apr_status_t Rivet_Finalize(void* data)
{

    RIVET_MPM_BRIDGE_CALL(child_finalize,data);
    apr_threadkey_private_delete (rivet_thread_key);

    return OK;
}

static void Rivet_ChildInit (apr_pool_t *pChild, server_rec *server)
{
    int                 idx;
    rivet_server_conf*  root_server_conf;
    server_rec*         s;

    /* the thread key used to access to Tcl threads private data */

    ap_assert (apr_threadkey_private_create (&rivet_thread_key, NULL, pChild) == APR_SUCCESS);

    /* This code is run once per child process. The forking 
     * of a child process doesn't preserve the thread where the Tcl 
     * notifier runs. The Notifier should have been restarted by one the 
     * pthread_atfork callbacks (setup in Tcl >= 8.5.14 and Tcl >= 8.6.1). In
     * case pthread_atfork is not supported we unconditionally call Tcl_InitNotifier
     * hoping for the best (Bug #55153)      
     */

#if !defined(HAVE_PTHREAD_ATFORK)
    Tcl_InitNotifier();
#endif

    /* We can rely on the existence of module_globals only we are
     * running the prefork MPM, otherwise the pointer is NULL and
     * the structure has to be filled with data
     */

    if (module_globals == NULL)
    {
        module_globals = Rivet_CreateModuleGlobals(pChild);
        module_globals->rivet_mpm_bridge = Rivet_SeekMPMBridge(pChild);
        module_globals->server = server;
    }

    /* This mutex should protect the process wide pool from concurrent access by 
     * different threads
     */

    apr_thread_mutex_create(&module_globals->pool_mutex, APR_THREAD_MUTEX_UNNESTED, pChild);

    /* Once we have established a pool with the same lifetime of the child process we
     * process all the configured server records assigning an integer as unique key 
     * to each of them 
     */

    root_server_conf = RIVET_SERVER_CONF(server->module_config);
    idx = 0;
    for (s = server; s != NULL; s = s->next)
    {
        rivet_server_conf*  myrsc;

        myrsc = RIVET_SERVER_CONF(s->module_config);

        /* We only have a different rivet_server_conf if MergeConfig
         * was called. We really need a separate one for each server,
         * so we go ahead and create one here, if necessary. */

        if (s != server && myrsc == root_server_conf) {
            myrsc = RIVET_NEW_CONF(pChild);
            ap_set_module_config(s->module_config,&rivet_module,myrsc);
            Rivet_CopyConfig(root_server_conf,myrsc);
        }

        myrsc->idx = idx++;
    }
    module_globals->vhosts_count = idx;

    /* Calling the brigde child process initialization */

    RIVET_MPM_BRIDGE_CALL(thread_init,pChild,server);

    apr_pool_cleanup_register(pChild,server,Rivet_Finalize,Rivet_Finalize);
}


static int Rivet_Handler (request_rec *r)    
{
    rivet_req_ctype ctype = Rivet_CheckType(r);  
    if (ctype == CTYPE_NOT_HANDLED) {
        return DECLINED;
    }

    return (*RIVET_MPM_BRIDGE_FUNCTION(request_processor))(r,ctype);
}

static int Rivet_InitGlobals (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp)
{
    /* the module global structure is allocated and the MPM bridge name established */

    module_globals = Rivet_CreateModuleGlobals (pPool);
    return OK;
}

/*
 * -- rivet_register_hooks: mod_rivet basic setup.
 *
 * 
 */

static void rivet_register_hooks(apr_pool_t *p)
{
    ap_hook_pre_config  (Rivet_InitGlobals,NULL, NULL, APR_HOOK_LAST);
    ap_hook_post_config (Rivet_ServerInit, NULL, NULL, APR_HOOK_LAST);
    ap_hook_handler     (Rivet_Handler,    NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_child_init  (Rivet_ChildInit,  NULL, NULL, APR_HOOK_LAST);
}

/* mod_rivet basic structures */

/* configuration commands and directives */

const command_rec rivet_cmds[] =
{
    AP_INIT_TAKE2 ("RivetServerConf", Rivet_ServerConf, NULL, RSRC_CONF, NULL),
    AP_INIT_TAKE2 ("RivetDirConf", Rivet_DirConf, NULL, ACCESS_CONF, NULL),
    AP_INIT_TAKE2 ("RivetUserConf", Rivet_UserConf, NULL, ACCESS_CONF|OR_FILEINFO,
                   "RivetUserConf key value: sets RivetUserConf(key) = value"),
    {NULL}
};

/* Dispatch list for API hooks */

module AP_MODULE_DECLARE_DATA rivet_module = 
{
    STANDARD20_MODULE_STUFF, 
    Rivet_CreateDirConfig,  /* create per-dir config structures    */
    Rivet_MergeDirConfig,   /* merge  per-dir config structures    */
    Rivet_CreateConfig,     /* create per-server config structures */
    Rivet_MergeConfig,      /* merge  per-server config structures */
    rivet_cmds,             /* table of config file commands       */
    rivet_register_hooks    /* register hooks                      */
};

