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

/*
 * This is a very basic splitter/combiner module as a demonstrator
 * for a multi-context transport protocol. The HTTP headers and
 * HTTP body will be transmitted in different TLMSP contexts,
 * this module will interact with mod_ssl to combine incomming data
 * and split outgoing data appropriately  */

#include "cs_hooks.h"
#include "cs_config.h"
//#include "httpd.h"
//#include "http_config.h"
//#include "http_core.h"
//#include "http_log.h"
//#include "http_main.h"
#include "http_protocol.h"
#include "http_request.h"
//#include "util_script.h"
#include "http_connection.h"
#ifdef HAVE_UNIX_SUEXEC
#include "unixd.h"
#endif
//#include "scoreboard.h"
//#include "mpm_common.h"

//#include "apr_strings.h"

//#include <stdio.h>



/*
 * Declare ourselves so the configuration routines can find and know us.
 * We'll fill it in at the end of the module.
 */
module AP_MODULE_DECLARE_DATA g_ContextsplitModule;



/*
 * You *could* change the following if you wanted to see the calling
 * sequence reported in the server's error_log, but beware - almost all of
 * these co-routines are called for every single request, and the impact
 * on the size (and readability) of the error_log is considerable.
 */
#ifndef EXAMPLE_LOG_EACH
#define EXAMPLE_LOG_EACH 0
#endif

#if EXAMPLE_LOG_EACH
static void example_log_each(apr_pool_t *p, server_rec *s, const char *note)
{
    if (s != NULL) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02991)
                     "mod_example_hooks: %s", note);
    }
    else {
        apr_file_t *out = NULL;
        apr_file_open_stderr(&out, p);
        apr_file_printf(out, "mod_example_hooks traced in non-loggable "
                        "context: %s\n", note);
    }
}
#endif

/*
 * This utility routine traces the hooks called when the server starts up.
 * It leaves a trace in a global variable, so it should not be called from
 * a hook handler that runs in a multi-threaded situation.
 */

static void trace_startup(apr_pool_t *p, server_rec *s, cs_cfg *mconfig,
                          const char *note)
{
	/*TODO*/
}


/*
 * This utility route traces the hooks called as a request is handled.
 * It takes the current request as argument
 */

static void trace_request(const request_rec *r, const char *note)
{
	/*TODO*/
}

/*
 * This utility routine traces the hooks called while processing a
 * Connection. Its trace is kept in the pool notes of the pool associated
 * with the Connection.
 */

/*
 * Key to get and set the userdata.  We should be able to get away
 * with a constant key, since in prefork mode the process will have
 * the connection and its pool to itself entirely, and in
 * multi-threaded mode each connection will have its own pool.
 */
static void trace_connection(conn_rec *c, const char *note)
{
	/*TODO*/
}

void trace_nocontext(apr_pool_t *p, const char *file, int line,
                            const char *note)
{
	/*TODO*/
}

/*--------------------------------------------------------------------------*/
/*                                                                          */
/* Which functions are responsible for which hooks in the server.           */
/*                                                                          */
/*--------------------------------------------------------------------------*/
/*
 * Each function our module provides to handle a particular hook is
 * specified here.  The functions are registered using
 * ap_hook_foo(name, predecessors, successors, position)
 * where foo is the name of the hook.
 *
 * The args are as follows:
 * name         -> the name of the function to call.
 * predecessors -> a list of modules whose calls to this hook must be
 *                 invoked before this module.
 * successors   -> a list of modules whose calls to this hook must be
 *                 invoked after this module.
 * position     -> The relative position of this module.  One of
 *                 APR_HOOK_FIRST, APR_HOOK_MIDDLE, or APR_HOOK_LAST.
 *                 Most modules will use APR_HOOK_MIDDLE.  If multiple
 *                 modules use the same relative position, Apache will
 *                 determine which to call first.
 *                 If your module relies on another module to run first,
 *                 or another module running after yours, use the
 *                 predecessors and/or successors.
 *
 * The number in brackets indicates the order in which the routine is called
 * during request processing.  Note that not all routines are necessarily
 * called (such as if a resource doesn't have access restrictions).
 * The actual delivery of content to the browser [9] is not handled by
 * a hook; see the handler declarations below.
 */
static void
cs_register_hooks(apr_pool_t *p)
{
    ap_hook_pre_config(cs_hooka_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_check_config(cs_hooka_check_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_test_config(cs_hookv_test_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_open_logs(cs_hooka_open_logs, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_post_config(cs_hooka_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_child_init(cs_hookv_child_init, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_handler(cs_hookf_handler, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_quick_handler(cs_hookf_quick_handler, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_pre_connection(cs_hooka_pre_connection, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_process_connection(cs_hookf_process_connection, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_pre_read_request(cs_hookv_pre_read_request, NULL, NULL,
                              APR_HOOK_MIDDLE);
    /* [1] post read_request handling */
    ap_hook_post_read_request(cs_hooka_post_read_request, NULL, NULL,
                              APR_HOOK_MIDDLE);
    ap_hook_log_transaction(cs_hooka_log_transaction, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_http_scheme(cs_hookf_http_scheme, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_default_port(cs_hookf_default_port, NULL, NULL, APR_HOOK_LAST);
    ap_hook_translate_name(cs_hookf_translate_name, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_map_to_storage(cs_hookf_map_to_storage, NULL,NULL, APR_HOOK_MIDDLE);
    ap_hook_header_parser(cs_hooka_header_parser, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_fixups(cs_hooka_fixups, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_type_checker(cs_hookf_type_checker, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_check_access(cs_hooka_check_access, NULL, NULL, APR_HOOK_MIDDLE,
                         AP_AUTH_INTERNAL_PER_CONF);
    ap_hook_check_authn(cs_hookf_check_authn, NULL, NULL, APR_HOOK_MIDDLE,
                        AP_AUTH_INTERNAL_PER_CONF);
    ap_hook_check_authz(cs_hookf_check_authz, NULL, NULL, APR_HOOK_MIDDLE,
                        AP_AUTH_INTERNAL_PER_CONF);
    ap_hook_insert_filter(cs_hookv_insert_filter, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_insert_error_filter(cs_hookv_insert_error_filter, NULL, NULL, APR_HOOK_MIDDLE);
#ifdef HAVE_UNIX_SUEXEC
    ap_hook_get_suexec_identity(cs_hookf_get_suexec_identity, NULL, NULL, APR_HOOK_MIDDLE);
#endif
    ap_hook_create_connection(cs_hookf_create_connection, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_get_mgmt_items(cs_hooka_get_mgmt_items, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_create_request(cs_hooka_create_request, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_pre_mpm(cs_hooka_pre_mpm, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_monitor(cs_hooka_monitor, NULL, NULL, APR_HOOK_MIDDLE);


}

/*--------------------------------------------------------------------------*/
/*                                                                          */
/* All of the routines have been declared now.  Here's the list of          */
/* directives specific to our module, and information about where they      */
/* may appear and how the command parser should pass them to us for         */
/* processing.  Note that care must be taken to ensure that there are NO    */
/* collisions of directive names between modules.                           */
/*                                                                          */
/*--------------------------------------------------------------------------*/
/*
 * List of directives specific to our module.
 */
static const command_rec cs_cmds[] =
{
#if 0
		AP_INIT_NO_ARGS(
        "Example",                          /* directive name */
        cmd_example,                        /* config action routine */
        NULL,                               /* argument to include in call */
        OR_OPTIONS,                         /* where available */
        "Example directive - no arguments"  /* directive description */
    ),
#endif
    {NULL}
};
/*--------------------------------------------------------------------------*/
/*                                                                          */
/* Finally, the list of callback routines and data structures that provide  */
/* the static hooks into our module from the other parts of the server.     */
/*                                                                          */
/*--------------------------------------------------------------------------*/
/*
 * Module definition for configuration.  If a particular callback is not
 * needed, replace its routine name below with the word NULL.
 */
AP_DECLARE_MODULE(example_hooks) =
{
    STANDARD20_MODULE_STUFF,
    cs_create_dir_config,    /* per-directory config creator */
    cs_merge_dir_config,     /* dir config merger */
    cs_create_server_config, /* server config creator */
    cs_merge_server_config,  /* server config merger */
    cs_cmds,                 /* command table */
    cs_register_hooks,       /* set up other request processing hooks */
};
