/* Copyright 2001-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"

#define EnvMgObj SvMAGIC((SV*)ENVHV)->mg_ptr
#define EnvMgLen SvMAGIC((SV*)ENVHV)->mg_len

/* XXX: move to utils? */
static unsigned long modperl_interp_address(pTHX)
{
#ifdef USE_ITHREADS
    return (unsigned long)aTHX;
#else
    return (unsigned long)0; /* just one interpreter */
#endif
}

#define MP_ENV_HV_STORE(hv, key, val) STMT_START {              \
        I32 klen = strlen(key);                                 \
        SV **svp = hv_fetch(hv, key, klen, FALSE);              \
                                                                \
        if (svp) {                                              \
            sv_setpv(*svp, val);                                \
        }                                                       \
        else {                                                  \
            SV *sv = newSVpv(val, 0);                           \
            hv_store(hv, key, klen, sv, FALSE);                 \
            modperl_envelem_tie(sv, key, klen);                 \
            svp = &sv;                                          \
        }                                                       \
        MP_TRACE_e(MP_FUNC, "$ENV{%s} = \"%s\";", key, val);    \
                                                                \
        SvTAINTED_on(*svp);                                     \
    } STMT_END

void modperl_env_hv_store(pTHX_ const char *key, const char *val)
{
    MP_ENV_HV_STORE(ENVHV, key, val);
}

static MP_INLINE
void modperl_env_hv_delete(pTHX_ HV *hv, char *key)
{
    I32 klen = strlen(key);
    if (hv_exists(hv, key, klen)) {
        hv_delete(hv, key, strlen(key), G_DISCARD);
    }
}

typedef struct {
    const char *key;
    I32 klen;
    const char *val;
    I32 vlen;
    U32 hash;
} modperl_env_ent_t;

#define MP_ENV_ENT(k,v) \
{ k, MP_SSTRLEN(k), v, MP_SSTRLEN(v), 0 }

static modperl_env_ent_t MP_env_const_vars[] = {
    MP_ENV_ENT("MOD_PERL", MP_VERSION_STRING),
    MP_ENV_ENT("MOD_PERL_API_VERSION", MP_API_VERSION),
    { NULL }
};

void modperl_env_hash_keys(pTHX)
{
    modperl_env_ent_t *ent = MP_env_const_vars;

    while (ent->key) {
        PERL_HASH(ent->hash, ent->key, ent->klen);
        MP_TRACE_e(MP_FUNC, "[0x%lx] PERL_HASH: %s (len: %d)",
                   modperl_interp_address(aTHX), ent->key, ent->klen);
        ent++;
    }
}

void modperl_env_clear(pTHX)
{
    HV *hv = ENVHV;
    U32 mg_flags;

    modperl_env_untie(mg_flags);

    MP_TRACE_e(MP_FUNC, "[0x%lx] %%ENV = ();", modperl_interp_address(aTHX));

    hv_clear(hv);

    modperl_env_tie(mg_flags);
}

#define MP_ENV_HV_STORE_TABLE_ENTRY(hv, elt)    \
    MP_ENV_HV_STORE(hv, elt.key, elt.val);

static void modperl_env_table_populate(pTHX_ apr_table_t *table)
{
    HV *hv = ENVHV;
    U32 mg_flags;
    int i;
    const apr_array_header_t *array;
    apr_table_entry_t *elts;

    modperl_env_untie(mg_flags);

    array = apr_table_elts(table);
    elts  = (apr_table_entry_t *)array->elts;

    for (i = 0; i < array->nelts; i++) {
        if (!elts[i].key || !elts[i].val) {
            continue;
        }
        MP_ENV_HV_STORE_TABLE_ENTRY(hv, elts[i]);
    }    

    modperl_env_tie(mg_flags);
}

static void modperl_env_table_unpopulate(pTHX_ apr_table_t *table)
{
    HV *hv = ENVHV;
    U32 mg_flags;
    int i;
    const apr_array_header_t *array;
    apr_table_entry_t *elts;

    modperl_env_untie(mg_flags);

    array = apr_table_elts(table);
    elts  = (apr_table_entry_t *)array->elts;

    for (i = 0; i < array->nelts; i++) {
        if (!elts[i].key) {
            continue;
        }
        modperl_env_hv_delete(aTHX_ hv, elts[i].key);
        MP_TRACE_e(MP_FUNC, "delete $ENV{%s};", elts[i].key);
    }

    modperl_env_tie(mg_flags);
}

/* see the comment in modperl_env_sync_env_hash2table */
static void modperl_env_sync_table(pTHX_ apr_table_t *table)
{
    int i;
    const apr_array_header_t *array;
    apr_table_entry_t *elts;
    HV *hv = ENVHV;
    SV **svp;
    
    array = apr_table_elts(table);
    elts  = (apr_table_entry_t *)array->elts;
    
    for (i = 0; i < array->nelts; i++) {
        if (!elts[i].key) {
            continue;
        }
        svp = hv_fetch(hv, elts[i].key, strlen(elts[i].key), FALSE);
        if (svp) {
            apr_table_set(table, elts[i].key, SvPV_nolen(*svp));
            MP_TRACE_e(MP_FUNC, "(Set|Pass)Env '%s' '%s'", elts[i].key,
                       SvPV_nolen(*svp));
        }
    }    
    TAINT_NOT; /* SvPV_* causes the taint issue */
}

/* Make per-server PerlSetEnv and PerlPassEnv in sync with %ENV at
 * config time (if perl is running), by copying %ENV values to the
 * PerlSetEnv and PerlPassEnv tables (only for keys which are already
 * in those tables)
 */
void modperl_env_sync_srv_env_hash2table(pTHX_ apr_pool_t *p,
                                         modperl_config_srv_t *scfg)
{
    modperl_env_sync_table(aTHX_ scfg->SetEnv);
    modperl_env_sync_table(aTHX_ scfg->PassEnv);
}

void modperl_env_sync_dir_env_hash2table(pTHX_ apr_pool_t *p,
                                         modperl_config_dir_t *dcfg)
{
    modperl_env_sync_table(aTHX_ dcfg->SetEnv);
}

/* list of environment variables to pass by default */
static const char *MP_env_pass_defaults[] = {
    "PATH", "TZ", NULL
};

void modperl_env_configure_server(pTHX_ apr_pool_t *p, server_rec *s)
{
    MP_dSCFG(s);
    int i = 0;

    /* make per-server PerlSetEnv and PerlPassEnv entries visible
     * to %ENV at config time
     */

    for (i=0; MP_env_pass_defaults[i]; i++) {
        const char *key = MP_env_pass_defaults[i];
        char *val;

        if (apr_table_get(scfg->SetEnv, key) ||
            apr_table_get(scfg->PassEnv, key))
        {
            continue; /* already configured */
        }

        if ((val = getenv(key))) {
            apr_table_set(scfg->PassEnv, key, val);
        }
    }

    MP_TRACE_e(MP_FUNC, "\n\t[%s/0x%lx/%s]"
               "\n\t@ENV{keys scfg->SetEnv} = values scfg->SetEnv;",
               modperl_pid_tid(p), modperl_interp_address(aTHX),
               modperl_server_desc(s, p));
    modperl_env_table_populate(aTHX_ scfg->SetEnv);

    MP_TRACE_e(MP_FUNC, "\n\t[%s/0x%lx/%s]"
               "\n\t@ENV{keys scfg->PassEnv} = values scfg->PassEnv;",
               modperl_pid_tid(p), modperl_interp_address(aTHX),
               modperl_server_desc(s, p));
    modperl_env_table_populate(aTHX_ scfg->PassEnv);
}

#define overlay_subprocess_env(r, tab) \
    r->subprocess_env = apr_table_overlay(r->pool, \
                                          r->subprocess_env, \
                                          tab)

void modperl_env_configure_request_dir(pTHX_ request_rec *r)
{
    MP_dRCFG;
    MP_dDCFG;

    /* populate %ENV and r->subprocess_env with per-directory 
     * PerlSetEnv entries.
     *
     * note that per-server PerlSetEnv entries, as well as
     * PerlPassEnv entries (which are only per-server), are added
     * to %ENV and r->subprocess_env via modperl_env_configure_request_srv
     */

    if (!apr_is_empty_table(dcfg->SetEnv)) {
        apr_table_t *setenv_copy;

        /* add per-directory PerlSetEnv entries to %ENV
         * collisions with per-server PerlSetEnv entries are 
         * resolved via the nature of a Perl hash
         */
        MP_TRACE_e(MP_FUNC, "\n\t[%s/0x%lx/%s]"
                   "\n\t@ENV{keys dcfg->SetEnv} = values dcfg->SetEnv;",
                   modperl_pid_tid(r->pool), modperl_interp_address(aTHX),
                   modperl_server_desc(r->server, r->pool));
        modperl_env_table_populate(aTHX_ dcfg->SetEnv);

        /* make sure the entries are in the subprocess_env table as well.
         * we need to use apr_table_overlap (not apr_table_overlay) because
         * r->subprocess_env might have per-server PerlSetEnv entries in it
         * and using apr_table_overlay would generate duplicate entries.
         * in order to use apr_table_overlap, though, we need to copy the
         * the dcfg table so that pool requirements are satisfied */

        setenv_copy = apr_table_copy(r->pool, dcfg->SetEnv);
        apr_table_overlap(r->subprocess_env, setenv_copy, APR_OVERLAP_TABLES_SET);
    }

    MpReqPERL_SET_ENV_DIR_On(rcfg);
}

void modperl_env_configure_request_srv(pTHX_ request_rec *r)
{
    MP_dRCFG;
    MP_dSCFG(r->server);

    /* populate %ENV and r->subprocess_env with per-server PerlSetEnv 
     * and PerlPassEnv entries.  
     *
     * although both are setup in %ENV in modperl_request_configure_server
     * %ENV will be reset via modperl_env_request_unpopulate.
     */

    if (!apr_is_empty_table(scfg->SetEnv)) {
        MP_TRACE_e(MP_FUNC, "\n\t[%s/0x%lx/%s]"
                   "\n\t@ENV{keys scfg->SetEnv} = values scfg->SetEnv;",
                   modperl_pid_tid(r->pool), modperl_interp_address(aTHX),
                   modperl_server_desc(r->server, r->pool));
        modperl_env_table_populate(aTHX_ scfg->SetEnv);

        overlay_subprocess_env(r, scfg->SetEnv);
    }

    if (!apr_is_empty_table(scfg->PassEnv)) {
        MP_TRACE_e(MP_FUNC, "\n\t[%s/0x%lx/%s]"
                   "\n\t@ENV{keys scfg->PassEnv} = values scfg->PassEnv;",
                   modperl_pid_tid(r->pool), modperl_interp_address(aTHX),
                   modperl_server_desc(r->server, r->pool));
        modperl_env_table_populate(aTHX_ scfg->PassEnv);

        overlay_subprocess_env(r, scfg->PassEnv);
    }

    MpReqPERL_SET_ENV_SRV_On(rcfg);
}

void modperl_env_default_populate(pTHX)
{
    modperl_env_ent_t *ent = MP_env_const_vars;
    HV *hv = ENVHV;
    U32 mg_flags;

    modperl_env_untie(mg_flags);

    while (ent->key) {
        SV *sv = newSVpvn(ent->val, ent->vlen);
        hv_store(hv, ent->key, ent->klen,
                 sv, ent->hash);
        MP_TRACE_e(MP_FUNC, "$ENV{%s} = \"%s\";", ent->key, ent->val);
        modperl_envelem_tie(sv, ent->key, ent->klen);
        ent++;
    }

    modperl_env_tie(mg_flags);
}

void modperl_env_request_populate(pTHX_ request_rec *r)
{
    MP_dRCFG;

    /* this is called under the following conditions
     *   - if PerlOptions +SetupEnv
     *   - if $r->subprocess_env() is called in a void context with no args
     *
     * normally, %ENV is only populated once per request (if at all) -
     * just prior to content generation if +SetupEnv.
     *
     * however, in the $r->subprocess_env() case it will be called 
     * more than once - once for each void call, and once again just
     * prior to content generation.  while costly, the multiple
     * passes are required, otherwise void calls would prohibit later
     * phases from populating %ENV with new subprocess_env table entries
     */

    MP_TRACE_e(MP_FUNC, "\n\t[%s/0x%lx/%s%s]"
               "\n\t@ENV{keys r->subprocess_env} = values r->subprocess_env;",
               modperl_pid_tid(r->pool), modperl_interp_address(aTHX),
               modperl_server_desc(r->server, r->pool), r->uri);

    /* we can eliminate some of the cost by only doing CGI variables once
     * per-request no matter how many times $r->subprocess_env() is called
     */
    if (! MpReqSETUP_ENV(rcfg)) {

        ap_add_common_vars(r);
        ap_add_cgi_vars(r);

    }

    modperl_env_table_populate(aTHX_ r->subprocess_env);

    /* don't set up CGI variables again this request.
     * this also triggers modperl_env_request_unpopulate, which
     * resets %ENV between requests - see modperl_config_request_cleanup 
     */
    MpReqSETUP_ENV_On(rcfg);
}

void modperl_env_request_unpopulate(pTHX_ request_rec *r)
{
    MP_dRCFG;

    /* unset only once */
    if (!MpReqSETUP_ENV(rcfg)) {
        return;
    }

    MP_TRACE_e(MP_FUNC,
               "\n\t[%s/0x%lx/%s%s]\n\tdelete @ENV{keys r->subprocess_env};",
               modperl_pid_tid(r->pool), modperl_interp_address(aTHX),
               modperl_server_desc(r->server, r->pool), r->uri);
    modperl_env_table_unpopulate(aTHX_ r->subprocess_env);

    MpReqSETUP_ENV_Off(rcfg);
}

void modperl_env_request_tie(pTHX_ request_rec *r)
{
    EnvMgObj = (char *)r;
    EnvMgLen = -1;

#ifdef MP_PERL_HV_GMAGICAL_AWARE
    MP_TRACE_e(MP_FUNC, "[%s/0x%lx] tie %%ENV, $r\n\t (%s%s)",
               modperl_pid_tid(r->pool), modperl_interp_address(aTHX),
               modperl_server_desc(r->server, r->pool), r->uri);
    SvGMAGICAL_on((SV*)ENVHV);
#endif
}

void modperl_env_request_untie(pTHX_ request_rec *r)
{
    EnvMgObj = NULL;

#ifdef MP_PERL_HV_GMAGICAL_AWARE
    MP_TRACE_e(MP_FUNC, "[%s/0x%lx] untie %%ENV; # from r\n\t (%s%s)",
               modperl_pid_tid(r->pool), modperl_interp_address(aTHX),
               modperl_server_desc(r->server, r->pool), r->uri);
    SvGMAGICAL_off((SV*)ENVHV);
#endif
}

/* to store the original virtual tables
 * these are global, not per-interpreter
 */
static MGVTBL MP_PERL_vtbl_env;
static MGVTBL MP_PERL_vtbl_envelem;

#define MP_PL_vtbl_call(name, meth) \
    MP_PERL_vtbl_##name.svt_##meth(aTHX_ sv, mg)

#define MP_dENV_KEY \
    STRLEN klen; \
    const char *key = (const char *)MgPV(mg,klen)

#define MP_dENV_VAL \
    STRLEN vlen; \
    const char *val = (const char *)SvPV(sv,vlen)

/*
 * XXX: what we do here might change:
 *      - make it optional for %ENV to be tied to r->subprocess_env
 *      - make it possible to modify environ
 *      - we could allow modification of environ if mpm isn't threaded
 *      - we could allow modification of environ if variable isn't a CGI
 *        variable (still could cause problems)
 */
/*
 * problems we are trying to solve:
 *      - environ is shared between threads
 *          + Perl does not serialize access to environ
 *          + even if it did, CGI variables cannot be shared between threads!
 * problems we create by trying to solve above problems:
 *      - a forked process will not inherit the current %ENV
 *      - C libraries might rely on environ, e.g. DBD::Oracle
 */
static int modperl_env_magic_set_all(pTHX_ SV *sv, MAGIC *mg)
{
    request_rec *r = (request_rec *)EnvMgObj;

    if (r) {
        if (PL_localizing) {
            /* local %ENV = (FOO => 'bar', BIZ => 'baz') */
            HE *entry;
            STRLEN n_a;

            hv_iterinit((HV*)sv);
            while ((entry = hv_iternext((HV*)sv))) {
                I32 keylen;
                apr_table_set(r->subprocess_env,
                              hv_iterkey(entry, &keylen),
                              SvPV(hv_iterval((HV*)sv, entry), n_a));
                MP_TRACE_e(MP_FUNC, "[%s/0x%lx] localizing: %s => %s",
                           modperl_pid_tid(r->pool),
                           modperl_interp_address(aTHX),
                           hv_iterkey(entry, &keylen),
                           SvPV(hv_iterval((HV*)sv, entry), n_a));
            }
        }
    }
    else {
#ifdef MP_TRACE
        HE *entry;
        STRLEN n_a;

        MP_TRACE_e(MP_FUNC,
                   "\n\t[%lu/0x%lx] populating %%ENV:",
                   (unsigned long)getpid(), modperl_interp_address(aTHX));

        hv_iterinit((HV*)sv);

        while ((entry = hv_iternext((HV*)sv))) {
                I32 keylen;
                MP_TRACE_e(MP_FUNC, "$ENV{%s} = \"%s\";",
                           modperl_pid_tid(r->pool),
                           modperl_interp_address(aTHX),
                           hv_iterkey(entry, &keylen),
                           SvPV(hv_iterval((HV*)sv, entry), n_a));
            }
#endif
        return MP_PL_vtbl_call(env, set);
    }

    return 0;
}

static int modperl_env_magic_clear_all(pTHX_ SV *sv, MAGIC *mg)
{
    request_rec *r = (request_rec *)EnvMgObj;

    if (r) {
        apr_table_clear(r->subprocess_env);
        MP_TRACE_e(MP_FUNC,
                   "[%s/0x%lx] clearing all magic off r->subprocess_env",
                   modperl_pid_tid(r->pool), modperl_interp_address(aTHX));
    }
    else {
        MP_TRACE_e(MP_FUNC,
                   "[%s/0x%lx] %%ENV = ();",
                   modperl_pid_tid(r->pool), modperl_interp_address(aTHX));
        return MP_PL_vtbl_call(env, clear);
    }

    return 0;
}

static int modperl_env_magic_set(pTHX_ SV *sv, MAGIC *mg)
{
    request_rec *r = (request_rec *)EnvMgObj;

    if (r) {
        MP_dENV_KEY;
        MP_dENV_VAL;
        apr_table_set(r->subprocess_env, key, val);
        MP_TRACE_e(MP_FUNC, "[%s/0x%lx] r->subprocess_env set: %s => %s",
                   modperl_pid_tid(r->pool),
                   modperl_interp_address(aTHX), key, val);
    }
    else {
#ifdef MP_TRACE
        MP_dENV_KEY;
        MP_dENV_VAL;
        MP_TRACE_e(MP_FUNC,
                   "[%lu/0x%lx] $ENV{%s} = \"%s\";",
                   (unsigned long)getpid(),
                   modperl_interp_address(aTHX), key, val);
#endif
        return MP_PL_vtbl_call(envelem, set);
    }

    return 0;
}

static int modperl_env_magic_clear(pTHX_ SV *sv, MAGIC *mg)
{
    request_rec *r = (request_rec *)EnvMgObj;

    if (r) {
        MP_dENV_KEY;
        apr_table_unset(r->subprocess_env, key);
        MP_TRACE_e(MP_FUNC, "[%s/0x%lx] r->subprocess_env unset: %s",
                   modperl_pid_tid(r->pool),
                   modperl_interp_address(aTHX), key);
    }
    else {
#ifdef MP_TRACE
        MP_dENV_KEY;
        MP_TRACE_e(MP_FUNC, "[%lu/0x%lx] delete $ENV{%s};",
                   (unsigned long)getpid(),
                   modperl_interp_address(aTHX), key);
#endif
        return MP_PL_vtbl_call(envelem, clear);
    }

    return 0;
}

#ifdef MP_PERL_HV_GMAGICAL_AWARE
static int modperl_env_magic_get(pTHX_ SV *sv, MAGIC *mg)
{
    request_rec *r = (request_rec *)EnvMgObj;

    if (r) {
        MP_dENV_KEY;
        const char *val;

        if ((val = apr_table_get(r->subprocess_env, key))) {
            sv_setpv(sv, val);
            MP_TRACE_e(MP_FUNC,
                       "[%s/0x%lx] r->subprocess_env get: %s => %s",
                       modperl_pid_tid(r->pool),
                       modperl_interp_address(aTHX), key, val);
        }
        else {
            sv_setsv(sv, &PL_sv_undef);
            MP_TRACE_e(MP_FUNC,
                       "[%s/0x%lx] r->subprocess_env get: %s => undef",
                       modperl_pid_tid(r->pool),
                       modperl_interp_address(aTHX), key);
        }
    }
    else {
        /* there is no svt_get in PL_vtbl_envelem */
#ifdef MP_TRACE
        MP_dENV_KEY;
        MP_TRACE_e(MP_FUNC,
                   "[%lu/0x%lx] there is no svt_get in PL_vtbl_envelem: %s",
                   (unsigned long)getpid(),
                   modperl_interp_address(aTHX), key);
#endif
    }

    return 0;
}
#endif

/* override %ENV virtual tables with our own */
static MGVTBL MP_vtbl_env = {
    0,
    MEMBER_TO_FPTR(modperl_env_magic_set_all),
    0,
    MEMBER_TO_FPTR(modperl_env_magic_clear_all),
    0
};

static MGVTBL MP_vtbl_envelem = {
    0,
    MEMBER_TO_FPTR(modperl_env_magic_set),
    0,
    MEMBER_TO_FPTR(modperl_env_magic_clear),
    0
};

void modperl_env_init(void)
{
    /* save originals */
    StructCopy(&PL_vtbl_env, &MP_PERL_vtbl_env, MGVTBL);
    StructCopy(&PL_vtbl_envelem, &MP_PERL_vtbl_envelem, MGVTBL);

    /* replace with our versions */
    StructCopy(&MP_vtbl_env, &PL_vtbl_env, MGVTBL);
    StructCopy(&MP_vtbl_envelem, &PL_vtbl_envelem, MGVTBL);
}

void modperl_env_unload(void)
{
    /* restore originals */
    StructCopy(&MP_PERL_vtbl_env, &PL_vtbl_env, MGVTBL);
    StructCopy(&MP_PERL_vtbl_envelem, &PL_vtbl_envelem, MGVTBL);
}
