/* mod_rivet_generator.c -- Content generation functions */

/*
    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 <httpd.h>
#include <tcl.h>
#include <apr_strings.h>

#include "mod_rivet.h"
#include "rivetParser.h"
#include "rivetCore.h"
#include "apache_config.h"
#include "TclWeb.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 "mod_rivet_common.h"
#include "mod_rivet_cache.h"

extern mod_rivet_globals* module_globals;
extern apr_threadkey_t*   rivet_thread_key;
extern module rivet_module;


/* 
 * -- Rivet_CheckType (request_rec *r)
 *
 * Utility function internally used to determine which type
 * of file (whether rvt template or plain Tcl script) we are
 * dealing with. In order to speed up multiple tests the
 * the test returns an integer (RIVET_TEMPLATE) for rvt templates
 * or RIVET_TCLFILE for Tcl scripts
 *
 * Argument: 
 *
 *    request_rec*: pointer to the current request record
 *
 * Returns:
 *
 *    integer number meaning the type of file we are dealing with
 *
 * Side effects:
 *
 *    none.
 *
 */

rivet_req_ctype
Rivet_CheckType (request_rec *req)
{
    rivet_req_ctype ctype = CTYPE_NOT_HANDLED;

    if ( req->handler != NULL ) {
        if (STRNEQU( req->handler, RIVET_TEMPLATE_CTYPE) ) {
            ctype  = RIVET_TEMPLATE;
        } else if ( STRNEQU( req->handler, RIVET_TCLFILE_CTYPE) ) {
            ctype = RIVET_TCLFILE;
        }
    }
    return ctype; 
}

/*
 * -- Rivet_ReleaseScript
 *
 *
 * 
 *
 *
 */

static void
Rivet_ReleaseScripts (running_scripts* scripts)
{
    if (scripts->rivet_before_script) Tcl_DecrRefCount(scripts->rivet_before_script);
    if (scripts->rivet_after_script) Tcl_DecrRefCount(scripts->rivet_after_script);
    if (scripts->rivet_error_script) Tcl_DecrRefCount(scripts->rivet_error_script);
    if (scripts->rivet_abort_script) Tcl_DecrRefCount(scripts->rivet_abort_script);
    if (scripts->after_every_script) Tcl_DecrRefCount(scripts->after_every_script);
}

/*
 * -- Rivet_SendContent
 *
 *   Set things up to execute a Tcl script or parse a rvt template, prepare
 *   the environment then execute it as a pure Tcl script
 *
 */

#define USE_APACHE_RSC

DLLEXPORT int
Rivet_SendContent(rivet_thread_private *private)
{
    int                     errstatus;
    int                     retval;
    Tcl_Interp*             interp;
    rivet_thread_interp*    interp_obj;
    Tcl_Channel*            running_channel;

    /* Set the global request req to know what we are dealing with in
     * case we have to call the PanicProc. */

    /* TODO: we can't place a pointer to the request rec here, if Tcl_Panic 
       gets called in general it won't have this pointer which has to be 
       thread private */

    private->rivet_panic_request_rec = private->r;

    // rsc = Rivet_GetConf(r);

    private->running_conf = RIVET_SERVER_CONF (private->r->server->module_config);

    #ifdef RIVET_DEBUG_BUILD
        ap_log_error(APLOG_MARK,APLOG_DEBUG,APR_SUCCESS,private->r->server,
                                MODNAME ": serving '%s' (%d)",private->r->server->server_hostname,
                                                              private->running_conf->idx);
    #endif

    /* the interp index in the private data can not be changed by a config merge */

    interp_obj = RIVET_PEEK_INTERP(private,private->running_conf);
    private->running = interp_obj->scripts;
    running_channel  = interp_obj->channel;

    if (private->r->per_dir_config)
    {
        rivet_server_conf* rdc = NULL;

        rdc = RIVET_SERVER_CONF(private->r->per_dir_config); 

        if ((rdc != NULL) && (rdc->path))
        {
            /* Let's check if a scripts object is already stored in the per-dir hash table */

            private->running = 
                (running_scripts *) apr_hash_get (interp_obj->per_dir_scripts,rdc->path,strlen(rdc->path));

            if (private->running == NULL)
            {
                rivet_server_conf*  newconfig   = NULL;
                running_scripts*    scripts     = 
                            (running_scripts *) apr_pcalloc (private->pool,sizeof(running_scripts));

                newconfig = RIVET_NEW_CONF(private->r->pool);

                Rivet_CopyConfig (private->running_conf,newconfig);
                Rivet_MergeDirConfigVars (private->r->pool,newconfig,private->running_conf,rdc);
                private->running_conf = newconfig;

                scripts = Rivet_RunningScripts (private->pool,scripts,newconfig);

                apr_hash_set (interp_obj->per_dir_scripts,rdc->path,strlen(rdc->path),scripts);
               
                private->running = scripts;
            }
        }

        if (USER_CONF_UPDATED(rdc))
        {
            rivet_server_conf* newconfig = NULL;
            private->running = (running_scripts *) apr_pcalloc (private->pool,sizeof(running_scripts));

            newconfig = RIVET_NEW_CONF(private->r->pool);

            Rivet_CopyConfig( private->running_conf, newconfig );
            Rivet_MergeDirConfigVars( private->r->pool, newconfig, private->running_conf, rdc );
            private->running_conf = newconfig;

            private->running = Rivet_RunningScripts(private->r->pool,private->running,newconfig);
        }
    }
    else
    {
        /* if no <Directory ...> rules applies we use the server configuration */

        private->running = interp_obj->scripts;
    }

    interp  = interp_obj->interp;

#ifndef USE_APACHE_RSC
    if (private->r->per_dir_config != NULL)
        rdc = RIVET_SERVER_CONF( private->r->per_dir_config );
    else
        rdc = rsc;
#endif

    private->r->allowed |= (1 << M_GET);
    private->r->allowed |= (1 << M_POST);
    private->r->allowed |= (1 << M_PUT);
    private->r->allowed |= (1 << M_DELETE);
    if (private->r->method_number != M_GET   && 
        private->r->method_number != M_POST  && 
        private->r->method_number != M_PUT   && 
        private->r->method_number != M_DELETE) {

        retval = DECLINED;
        goto sendcleanup;

    }

    if (private->r->finfo.filetype == 0)
    {
        request_rec* r = private->r;

        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, APR_EGENERAL, 
                     private->r->server,
                     MODNAME ": File does not exist: %s",
                     (r->path_info ? (char*)apr_pstrcat(r->pool, r->filename, r->path_info, NULL) : r->filename));
        retval = HTTP_NOT_FOUND;
        goto sendcleanup;
    }

    if ((errstatus = ap_meets_conditions(private->r)) != OK) {
        retval = errstatus;
        goto sendcleanup;
    }

    /* 
     * This one is the big catch when it comes to moving towards
     * Apache 2.0, or one of them, at least.
     */

    if (Rivet_chdir_file(private->r->filename) < 0)
    {
        request_rec* r = private->r;

        /* something went wrong doing chdir into r->filename, we are not specific
         * at this. We simply emit an internal server error and print a log message
         */
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, APR_EGENERAL, r->server, 
                     MODNAME ": Error accessing %s, could not chdir into directory", 
                     r->filename);

        retval = HTTP_INTERNAL_SERVER_ERROR;
        goto sendcleanup;
    }

    /* Apache Request stuff */

    TclWeb_InitRequest(private, interp);
    ApacheRequest_set_post_max(private->req->apachereq, private->running_conf->upload_max);
    ApacheRequest_set_temp_dir(private->req->apachereq, private->running_conf->upload_dir);

    /* Let's copy the request data into the thread private record */

    errstatus = ApacheRequest_parse(private->req->apachereq);
    if (errstatus != OK) {
        retval = errstatus;
        goto sendcleanup;
    }

    if (private->r->header_only && !private->running_conf->honor_header_only_reqs)
    {
        TclWeb_SetHeaderType(DEFAULT_HEADER_TYPE, private->req);
        TclWeb_PrintHeaders(private->req);
        retval = OK;
        goto sendcleanup;
    }

    /* If the user configuration has indeed been updated, I guess that
       pretty much invalidates anything that might have been cached. */

    /* This is all horrendously slow, and means we should *also* be
       doing caching on the modification time of the .htaccess files
       that concern us. FIXME */

    if (USER_CONF_UPDATED(private->running_conf) && (interp_obj->cache_size != 0) && 
                                                    (interp_obj->cache_free < interp_obj->cache_size)) 
    {
        RivetCache_Cleanup(private,interp_obj);
    }

    /* Rivet's master request script execution and exception handling */

    if (Tcl_EvalObjEx(interp, private->running->request_processing,0) == TCL_ERROR) 
    {
        /* we don't report errors coming from abort_page execution */

        if (!private->page_aborting) 
        {
            request_rec* r = private->r;

            ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r->server, 
                         MODNAME ": Error parsing exec file '%s': %s",
                         r->filename, Tcl_GetVar(interp, "errorInfo", 0));
        }
    }

    /* We don't keep user script until we find a way to cache them consistently */

    if (IS_USER_CONF(private->running_conf))
    {
        Rivet_ReleaseScripts(private->running);
        private->running_conf->user_scripts_status &= ~(unsigned int)USER_SCRIPTS_UPDATED;
    }

    /* We finalize the request processing by printing the headers
     * and flushing the rivet channel internal buffer */

    TclWeb_PrintHeaders(private->req);
    Tcl_Flush(*(running_channel));

    /* Reset globals */
    Rivet_CleanupRequest(private->r);

    retval = OK;
sendcleanup:

    /* Request processing final stage */

    /* A new big catch is the handling of exit commands that are treated
     * as ::rivet::abort_page. After the AbortScript has been evaluated
     * the exit condition is checked and in case the exit handler
     * of the bridge module is called before terminating the whole process
     */
    
    if (private->thread_exit)
    {
        ap_log_rerror(APLOG_MARK,APLOG_DEBUG,APR_SUCCESS,private->r, 
                                "process terminating with code %d",private->exit_status);
        RIVET_MPM_BRIDGE_CALL(exit_handler,private);

        //Tcl_Exit(private->exit_status);
        //exit(private->exit_status);
    }

    /* We now reset the status to prepare the child process for another request */

    private->req->content_sent = 0;
    if (private->abort_code != NULL)
    {
        Tcl_DecrRefCount(private->abort_code);
        private->abort_code = NULL;
    }
    private->page_aborting = 0;

    /* We reset this pointer to signal we have terminated the request processing */

    private->r = NULL;
    return retval;
}
