/* Copyright 2000-2005 The Apache Software Foundation
 *
 * Licensed 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 "mod_perl.h"

void *modperl_config_dir_create(apr_pool_t *p, char *dir)
{
    modperl_config_dir_t *dcfg = modperl_config_dir_new(p);

    dcfg->location = dir;

    MP_TRACE_d(MP_FUNC, "dir %s\n", dir);
    
#ifdef USE_ITHREADS
    /* defaults to per-server scope */
    dcfg->interp_scope = MP_INTERP_SCOPE_UNDEF;
#endif

    return dcfg;
}

#define merge_item(item) \
    mrg->item = add->item ? add->item : base->item

static apr_table_t *modperl_table_overlap(apr_pool_t *p,
                                          apr_table_t *base,
                                          apr_table_t *add)
{
    /* take the base (parent) values, and override with add (child) values,
     * generating a new table.  entries in add but not in base will be
     * added to the new table.  all using core apr table routines.
     *
     * note that this is equivalent to apr_table_overlap except a new
     * table is generated, which is required (otherwise we would clobber
     * the existing parent or child configurations)
     *
     * note that this is *not* equivalent to apr_table_overlap, although
     * I think it should be, because apr_table_overlap seems to clear
     * its first argument when the tables have different pools. I think
     * this is wrong -- rici
     */
    apr_table_t *merge = apr_table_overlay(p, base, add);

    /* compress will squash each key to the last value in the table.  this
     * is acceptable for all tables that expect only a single value per key
     * such as PerlPassEnv and PerlSetEnv.  PerlSetVar/PerlAddVar get their
     * own, non-standard, merge routines in merge_table_config_vars.
     */
    apr_table_compress(merge, APR_OVERLAP_TABLES_SET);

    return merge;
}

#define merge_table_overlap_item(item) \
    mrg->item = modperl_table_overlap(p, base->item, add->item)

static apr_table_t *merge_config_add_vars(apr_pool_t *p,
                                          const apr_table_t *base,
                                          const apr_table_t *unset,
                                          const apr_table_t *add)
{
    apr_table_t *temp = apr_table_copy(p, base);

    const apr_array_header_t *arr;
    apr_table_entry_t *entries;
    int i;

    /* for each key in unset do apr_table_unset(temp, key); */
    arr = apr_table_elts(unset);
    entries  = (apr_table_entry_t *)arr->elts;

    /* hopefully this is faster than using apr_table_do  */
    for (i = 0; i < arr->nelts; i++) {
        if (entries[i].key) {
            apr_table_unset(temp, entries[i].key);
        }
    }

    return apr_table_overlay(p, temp, add);
}

#define merge_handlers(merge_flag, array) \
    if (merge_flag(mrg)) { \
        mrg->array = modperl_handler_array_merge(p, \
                                                 base->array, \
                                                 add->array); \
    } \
    else { \
        merge_item(array); \
    }

void *modperl_config_dir_merge(apr_pool_t *p, void *basev, void *addv)
{
    int i;
    modperl_config_dir_t
        *base = (modperl_config_dir_t *)basev,
        *add  = (modperl_config_dir_t *)addv,
        *mrg  = modperl_config_dir_new(p);

    MP_TRACE_d(MP_FUNC, "basev==0x%lx, addv==0x%lx, mrg==0x%lx\n", 
               (unsigned long)basev, (unsigned long)addv,
               (unsigned long)mrg);

#ifdef USE_ITHREADS
    merge_item(interp_scope);
#endif

    mrg->flags = modperl_options_merge(p, base->flags, add->flags);

    merge_item(location);

    merge_table_overlap_item(SetEnv);

    /* this is where we merge PerlSetVar and PerlAddVar together */
    mrg->configvars = merge_config_add_vars(p,
                                            base->configvars,
                                            add->setvars, add->configvars);
    merge_table_overlap_item(setvars);

    /* XXX: check if Perl*Handler is disabled */
    for (i=0; i < MP_HANDLER_NUM_PER_DIR; i++) {
        merge_handlers(MpDirMERGE_HANDLERS, handlers_per_dir[i]);
    }

    return mrg;
}

modperl_config_req_t *modperl_config_req_new(request_rec *r)
{
    modperl_config_req_t *rcfg = 
        (modperl_config_req_t *)apr_pcalloc(r->pool, sizeof(*rcfg));

    MP_TRACE_d(MP_FUNC, "0x%lx\n", (unsigned long)rcfg);

    return rcfg;
}

modperl_config_srv_t *modperl_config_srv_new(apr_pool_t *p)
{
    modperl_config_srv_t *scfg = (modperl_config_srv_t *)
        apr_pcalloc(p, sizeof(*scfg));

    scfg->flags = modperl_options_new(p, MpSrvType);
    MpSrvENABLE_On(scfg); /* mod_perl enabled by default */
    MpSrvHOOKS_ALL_On(scfg); /* all hooks enabled by default */

    scfg->PerlModule  = apr_array_make(p, 2, sizeof(char *));
    scfg->PerlRequire = apr_array_make(p, 2, sizeof(char *));
    scfg->PerlPostConfigRequire =
        apr_array_make(p, 1, sizeof(modperl_require_file_t *));

    scfg->argv = apr_array_make(p, 2, sizeof(char *));

    scfg->setvars = apr_table_make(p, 2);
    scfg->configvars = apr_table_make(p, 2);

    scfg->PassEnv = apr_table_make(p, 2);
    scfg->SetEnv = apr_table_make(p, 2);

#ifdef MP_USE_GTOP
    scfg->gtop = modperl_gtop_new(p);
#endif        

    /* must copy ap_server_argv0, because otherwise any read/write of
     * $0 corrupts process' argv[0] (visible with 'ps -ef' on most
     * unices). This is due to the logic of calculating PL_origalen in
     * perl_parse, which is later used in set_mg.c:Perl_magic_set() to
     * truncate the argv[0] setting. remember that argv[0] passed to
     * perl_parse() != process's real argv[0].
     *
     * as a copying side-effect, changing $0 now doesn't affect the
     * way the process is seen from the outside.
     */
    modperl_config_srv_argv_push(apr_pstrmemdup(p, ap_server_argv0,
                                                strlen(ap_server_argv0)));

    MP_TRACE_d(MP_FUNC, "new scfg: 0x%lx\n", (unsigned long)scfg);

    return scfg;
}

modperl_config_dir_t *modperl_config_dir_new(apr_pool_t *p)
{
    modperl_config_dir_t *dcfg = (modperl_config_dir_t *)
        apr_pcalloc(p, sizeof(modperl_config_dir_t));

    dcfg->flags = modperl_options_new(p, MpDirType);

    dcfg->setvars = apr_table_make(p, 2);
    dcfg->configvars = apr_table_make(p, 2);

    dcfg->SetEnv = apr_table_make(p, 2);

    MP_TRACE_d(MP_FUNC, "new dcfg: 0x%lx\n", (unsigned long)dcfg);

    return dcfg;
}

#ifdef MP_TRACE
static void dump_argv(modperl_config_srv_t *scfg)
{
    int i;
    char **argv = (char **)scfg->argv->elts;
    modperl_trace(NULL, "modperl_config_srv_argv_init =>");
    for (i=0; i<scfg->argv->nelts; i++) {
        modperl_trace(NULL, "   %d = %s", i, argv[i]);
    }
}
#endif

char **modperl_config_srv_argv_init(modperl_config_srv_t *scfg, int *argc)
{
    modperl_config_srv_argv_push("-e;0");

    *argc = scfg->argv->nelts;

    MP_TRACE_g_do(dump_argv(scfg));

    return (char **)scfg->argv->elts;
}

void *modperl_config_srv_create(apr_pool_t *p, server_rec *s)
{
    modperl_config_srv_t *scfg = modperl_config_srv_new(p);

    if (!s->is_virtual) {

        /* give a chance to MOD_PERL_TRACE env var to set
         * PerlTrace. This place is the earliest point in mod_perl
         * configuration parsing, when we have the server object
         */
        modperl_trace_level_set_apache(s, NULL);

        /* Must store the global server record as early as possible,
         * because if mod_perl happens to be started from within a
         * vhost (e.g., PerlLoadModule) the base server record won't
         * be available to vhost and things will blow up
         */
        modperl_init_globals(s, p);
    }

    MP_TRACE_d(MP_FUNC, "p=0x%lx, s=0x%lx, virtual=%d\n",
               p, s, s->is_virtual);

#ifdef USE_ITHREADS

    scfg->interp_pool_cfg = 
        (modperl_tipool_config_t *)
        apr_pcalloc(p, sizeof(*scfg->interp_pool_cfg));

    scfg->interp_scope = MP_INTERP_SCOPE_REQUEST;

    /* XXX: determine reasonable defaults */
    scfg->interp_pool_cfg->start = 3;
    scfg->interp_pool_cfg->max_spare = 3;
    scfg->interp_pool_cfg->min_spare = 3;
    scfg->interp_pool_cfg->max = 5;
    scfg->interp_pool_cfg->max_requests = 2000;
#endif /* USE_ITHREADS */

    scfg->server = s;

    return scfg;
}

/* XXX: this is not complete */
void *modperl_config_srv_merge(apr_pool_t *p, void *basev, void *addv)
{
    int i;
    modperl_config_srv_t
        *base = (modperl_config_srv_t *)basev,
        *add  = (modperl_config_srv_t *)addv,
        *mrg  = modperl_config_srv_new(p);

    MP_TRACE_d(MP_FUNC, "basev==0x%lx, addv==0x%lx, mrg==0x%lx\n", 
               (unsigned long)basev, (unsigned long)addv,
               (unsigned long)mrg);

    merge_item(modules);
    merge_item(PerlModule);
    merge_item(PerlRequire);
    merge_item(PerlPostConfigRequire);

    merge_table_overlap_item(SetEnv);
    merge_table_overlap_item(PassEnv);

    /* this is where we merge PerlSetVar and PerlAddVar together */
    mrg->configvars = merge_config_add_vars(p,
                                            base->configvars,
                                            add->setvars, add->configvars);
    merge_table_overlap_item(setvars);

    merge_item(server);

#ifdef USE_ITHREADS
    merge_item(interp_pool_cfg);
    merge_item(interp_scope);
#else
    merge_item(perl);
#endif

    if (add->argv->nelts == 2 &&
        strEQ(((char **)add->argv->elts)[1], "+inherit"))
    {
        /* only inherit base PerlSwitches if explicitly told to */
        mrg->argv = base->argv;
    }
    else {
        mrg->argv = add->argv;
    }

    mrg->flags = modperl_options_merge(p, base->flags, add->flags);

    /* XXX: check if Perl*Handler is disabled */
    for (i=0; i < MP_HANDLER_NUM_PER_SRV; i++) {
        merge_handlers(MpSrvMERGE_HANDLERS, handlers_per_srv[i]);
    }
    for (i=0; i < MP_HANDLER_NUM_FILES; i++) {
        merge_handlers(MpSrvMERGE_HANDLERS, handlers_files[i]);
    }
    for (i=0; i < MP_HANDLER_NUM_PROCESS; i++) {
        merge_handlers(MpSrvMERGE_HANDLERS, handlers_process[i]);
    }
    for (i=0; i < MP_HANDLER_NUM_PRE_CONNECTION; i++) {
        merge_handlers(MpSrvMERGE_HANDLERS, handlers_pre_connection[i]);
    }
    for (i=0; i < MP_HANDLER_NUM_CONNECTION; i++) {
        merge_handlers(MpSrvMERGE_HANDLERS, handlers_connection[i]);
    }

    if (modperl_is_running()) {
        if (modperl_init_vhost(mrg->server, p, NULL) != OK) {
            exit(1); /*XXX*/
        }
    }

#ifdef USE_ITHREADS
    merge_item(mip);
#endif

    return mrg;
}

/* any per-request cleanup goes here */

apr_status_t modperl_config_request_cleanup(pTHX_ request_rec *r)
{
    apr_status_t retval;
    MP_dRCFG;

    retval = modperl_callback_per_dir(MP_CLEANUP_HANDLER, r, MP_HOOK_RUN_ALL);

    if (rcfg->pnotes) {
        SvREFCNT_dec(rcfg->pnotes);
        rcfg->pnotes = Nullhv;
    }

    /* undo changes to %ENV caused by +SetupEnv, perl-script, or
     * $r->subprocess_env, so the values won't persist  */
    if (MpReqSETUP_ENV(rcfg)) {
        modperl_env_request_unpopulate(aTHX_ r);
    }

    return retval;
}

apr_status_t modperl_config_req_cleanup(void *data)
{
    request_rec *r = (request_rec *)data;
    MP_dTHX;

    return modperl_config_request_cleanup(aTHX_ r);
}

void *modperl_get_perl_module_config(ap_conf_vector_t *cv)
{
    return ap_get_module_config(cv, &perl_module);
}

void modperl_set_perl_module_config(ap_conf_vector_t *cv, void *cfg)
{
    ap_set_module_config(cv, &perl_module, cfg);
}

int modperl_config_apply_PerlModule(server_rec *s,
                                    modperl_config_srv_t *scfg,
                                    PerlInterpreter *perl, apr_pool_t *p)
{
    char **entries;
    int i;
    dTHXa(perl);

    entries = (char **)scfg->PerlModule->elts;
    for (i = 0; i < scfg->PerlModule->nelts; i++){
        if (modperl_require_module(aTHX_ entries[i], TRUE)){
            MP_TRACE_d(MP_FUNC, "loaded Perl module %s for server %s\n",
                       entries[i], modperl_server_desc(s,p));
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                         "Can't load Perl module %s for server %s, exiting...",
                         entries[i], modperl_server_desc(s,p));
            return FALSE;
        }
    }

    return TRUE;
}

int modperl_config_apply_PerlRequire(server_rec *s,
                                     modperl_config_srv_t *scfg,
                                     PerlInterpreter *perl, apr_pool_t *p)
{
    char **entries;
    int i;
    dTHXa(perl);

    entries = (char **)scfg->PerlRequire->elts;
    for (i = 0; i < scfg->PerlRequire->nelts; i++){
        if (modperl_require_file(aTHX_ entries[i], TRUE)){
            MP_TRACE_d(MP_FUNC, "loaded Perl file: %s for server %s\n",
                       entries[i], modperl_server_desc(s,p));
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                         "Can't load Perl file: %s for server %s, exiting...",
                         entries[i], modperl_server_desc(s,p));
            return FALSE;
        }
    }

    return TRUE;
}

int modperl_config_apply_PerlPostConfigRequire(server_rec *s,
                                               modperl_config_srv_t *scfg,
                                               apr_pool_t *p)
{
    modperl_require_file_t **requires;
    int i;
    MP_PERL_CONTEXT_DECLARE;

    requires = (modperl_require_file_t **)scfg->PerlPostConfigRequire->elts;
    for (i = 0; i < scfg->PerlPostConfigRequire->nelts; i++){
        int retval;

        MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl);
        retval = modperl_require_file(aTHX_ requires[i]->file, TRUE);
        modperl_env_sync_srv_env_hash2table(aTHX_ p, scfg);
        modperl_env_sync_dir_env_hash2table(aTHX_ p, requires[i]->dcfg);
        MP_PERL_CONTEXT_RESTORE;

        if (retval) {
            MP_TRACE_d(MP_FUNC, "loaded Perl file: %s for server %s\n",
                       requires[i]->file, modperl_server_desc(s, p));
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                         "Can't load Perl file: %s for server %s, exiting...",
                         requires[i]->file, modperl_server_desc(s, p));
            
            return FALSE;
        }
    }

    return TRUE;
}

typedef struct {
    AV *av;
    I32 ix;
    PerlInterpreter *perl;
} svav_param_t;

static void *svav_getstr(void *buf, size_t bufsiz, void *param)
{
    svav_param_t *svav_param = (svav_param_t *)param;
    dTHXa(svav_param->perl);
    AV *av = svav_param->av;
    SV *sv;
    STRLEN n_a;

    if (svav_param->ix > AvFILL(av)) {
        return NULL;
    }

    sv = AvARRAY(av)[svav_param->ix++];
    SvPV_force(sv, n_a);

    apr_cpystrn(buf, SvPVX(sv), bufsiz);

    return buf;
}

const char *modperl_config_insert(pTHX_ server_rec *s,
                                  apr_pool_t *p,
                                  apr_pool_t *ptmp,
                                  int override,
                                  char *path,
                                  ap_conf_vector_t *conf,
                                  SV *lines)
{
    const char *errmsg;
    cmd_parms parms;
    svav_param_t svav_parms;
    ap_directive_t *conftree = NULL;

    memset(&parms, '\0', sizeof(parms));

    parms.limited = -1;
    parms.server = s;
    parms.override = override;
    parms.path = path;
    parms.pool = p;

    if (ptmp) {
        parms.temp_pool = ptmp;
    }
    else {
        apr_pool_create(&parms.temp_pool, p);
    }

    if (!(SvROK(lines) && (SvTYPE(SvRV(lines)) == SVt_PVAV))) {
        return "not an array reference";
    }

    svav_parms.av = (AV*)SvRV(lines);
    svav_parms.ix = 0;
#ifdef USE_ITHREADS
    svav_parms.perl = aTHX;
#endif

    parms.config_file = ap_pcfg_open_custom(p, "mod_perl",
                                            &svav_parms, NULL,
                                            svav_getstr, NULL);

    errmsg = ap_build_config(&parms, p, parms.temp_pool, &conftree);

    if (!errmsg) {
        errmsg = ap_walk_config(conftree, &parms, conf);
    }

    ap_cfg_closefile(parms.config_file);

    if (ptmp != parms.temp_pool) {
        apr_pool_destroy(parms.temp_pool);
    }

    return errmsg;
}

const char *modperl_config_insert_parms(pTHX_ cmd_parms *parms, 
                                        SV *lines)
{
    return modperl_config_insert(aTHX_ 
                                 parms->server, 
                                 parms->pool, 
                                 parms->temp_pool,
                                 parms->override, 
                                 parms->path,
                                 parms->context,
                                 lines);
}


const char *modperl_config_insert_server(pTHX_ server_rec *s, SV *lines)
{
    int override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
    apr_pool_t *p = s->process->pconf;

    return modperl_config_insert(aTHX_ s, p, NULL, override, NULL,
                                 s->lookup_defaults, lines);
}

const char *modperl_config_insert_request(pTHX_
                                          request_rec *r,
                                          SV *lines,
                                          int override)
{
    const char *errmsg;
    ap_conf_vector_t *dconf = ap_create_per_dir_config(r->pool);

    /* The path argument of "/" is only required to be non-NULL
       and "/" is as good a default as anything else */
    errmsg = modperl_config_insert(aTHX_
                                   r->server, r->pool, r->pool,
                                   override, "/",
                                   dconf, lines);

    if (errmsg) {
        return errmsg;
    }

    r->per_dir_config = 
        ap_merge_per_dir_configs(r->pool,
                                 r->per_dir_config,
                                 dconf);

    return NULL;
}


/* if r!=NULL check for dir PerlOptions, otherwise check for server
 * PerlOptions, (s must be always set)
 */
int modperl_config_is_perl_option_enabled(pTHX_ request_rec *r,
                                          server_rec *s, const char *name)
{
    U32 flag;
    MP_dSCFG(s);

    /* XXX: should we test whether perl is disabled for this server? */
    /*  if (!MpSrvENABLE(scfg)) { */
    /*      return 0;             */
    /*  }                         */

    if (r) {
        if ((flag = modperl_flags_lookup_dir(name))) {
            MP_dDCFG;
            return MpDirFLAGS(dcfg) & flag ? 1 : 0;
        }
        else {
            Perl_croak(aTHX_ "PerlOptions %s is not a directory option", name);
        }
    }
    else {
        if ((flag = modperl_flags_lookup_srv(name))) {
            return MpSrvFLAGS(scfg) & flag ? 1 : 0;
        }
        else {
            Perl_croak(aTHX_ "PerlOptions %s is not a server option", name);
        }
    }

}
