/* 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 "mod_perl.h"

/*
 * mgv = ModPerl Glob Value || Mostly Glob Value
 * as close to GV as we can get without actually using a GV
 * need config structures to be free of Perl structures
 */

#define modperl_mgv_new_w_name(mgv, p, n, copy)         \
    mgv = modperl_mgv_new(p);                           \
    mgv->len = strlen(n);                               \
    mgv->name = (copy ? apr_pstrndup(p, n, mgv->len) : n)

#define modperl_mgv_new_name(mgv, p, n)         \
    modperl_mgv_new_w_name(mgv, p, n, 1)

#define modperl_mgv_new_namen(mgv, p, n)        \
    modperl_mgv_new_w_name(mgv, p, n, 0)

int modperl_mgv_equal(modperl_mgv_t *mgv1,
                      modperl_mgv_t *mgv2)
{
    for (; mgv1 && mgv2; mgv1=mgv1->next, mgv2=mgv2->next) {
        if (mgv1->hash != mgv2->hash) {
            return FALSE;
        }
        if (mgv1->len != mgv2->len) {
            return FALSE;
        }
        if (memNE(mgv1->name, mgv2->name, mgv1->len)) {
            return FALSE;
        }
    }

    return TRUE;
}

modperl_mgv_t *modperl_mgv_new(apr_pool_t *p)
{
    return (modperl_mgv_t *)apr_pcalloc(p, sizeof(modperl_mgv_t));
}

#define modperl_mgv_get_next(mgv)               \
    if (mgv->name) {                            \
        mgv->next = modperl_mgv_new(p);         \
        mgv = mgv->next;                        \
    }

#define modperl_mgv_hash(mgv)                   \
    PERL_HASH(mgv->hash, mgv->name, mgv->len)
 /* MP_TRACE_h(MP_FUNC, "%s...hash=%ld", mgv->name, mgv->hash) */

modperl_mgv_t *modperl_mgv_compile(pTHX_ apr_pool_t *p,
                                   register const char *name)
{
    register const char *namend;
    I32 len;
    modperl_mgv_t *symbol = modperl_mgv_new(p);
    modperl_mgv_t *mgv = symbol;

    /* @mgv = split '::', $name */
    for (namend = name; *namend; namend++) {
        if (*namend == ':' && namend[1] == ':') {
            if ((len = (namend - name)) > 0) {
                modperl_mgv_get_next(mgv);
                mgv->name = apr_palloc(p, len+3);
                Copy(name, mgv->name, len, char);
                mgv->name[len++] = ':';
                mgv->name[len++] = ':';
                mgv->name[len] = '\0';
                mgv->len = len;
                modperl_mgv_hash(mgv);
            }
            name = namend + 2;
        }
    }

    modperl_mgv_get_next(mgv);

    mgv->len = namend - name;
    mgv->name = apr_pstrndup(p, name, mgv->len);
    modperl_mgv_hash(mgv);

    return symbol;
}

void modperl_mgv_append(pTHX_ apr_pool_t *p, modperl_mgv_t *symbol,
                        const char *name)
{
    modperl_mgv_t *mgv = symbol;

    while (mgv->next) {
        mgv = mgv->next;
    }

    mgv->name = apr_pstrcat(p, mgv->name, "::", NULL);
    mgv->len += 2;
    modperl_mgv_hash(mgv);

    mgv->next = modperl_mgv_compile(aTHX_ p, name);
}

/* faster replacement for gv_fetchpv() */
GV *modperl_mgv_lookup(pTHX_ modperl_mgv_t *symbol)
{
    HV *stash = PL_defstash;
    modperl_mgv_t *mgv;

    if (!symbol->hash) {
        /* special case for MyClass->handler */
        return (GV*)sv_2mortal(newSVpvn(symbol->name, symbol->len));
    }

    for (mgv = symbol; mgv; mgv = mgv->next) {
        HE *he = hv_fetch_he(stash, mgv->name, mgv->len, mgv->hash);
        if (he) {
            if (mgv->next) {
                stash = GvHV((GV *)HeVAL(he));
            }
            else {
                return (GV *)HeVAL(he);
            }
        }
        else {
            return (GV *)NULL;
        }
    }

    return (GV *)NULL;
}

#ifdef USE_ITHREADS
MP_INLINE GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol,
                                          server_rec *s, apr_pool_t *p)
{
    MP_dSCFG(s);
    GV *gv = modperl_mgv_lookup(aTHX_ symbol);

    if (gv || !MpSrvPARENT(scfg)) {
        return gv;
    }

    /*
     * this VirtualHost has its own parent interpreter
     * must require the module again with this server's THX
     */
    modperl_mgv_require_module(aTHX_ symbol, s, p);

    return modperl_mgv_lookup(aTHX_ symbol);
}
#else
MP_INLINE GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol,
                                          server_rec *s, apr_pool_t *p)
{
    return modperl_mgv_lookup(aTHX_ symbol);
}
#endif

/* currently used for complex filters attributes parsing */
/* XXX: may want to generalize it for any handlers */
#define MODPERL_MGV_DEEP_RESOLVE(handler, p)                   \
    if (handler->attrs & MP_FILTER_HAS_INIT_HANDLER) {         \
        modperl_filter_resolve_init_handler(aTHX_ handler, p); \
    }

int modperl_mgv_resolve(pTHX_ modperl_handler_t *handler,
                        apr_pool_t *p, const char *name, int logfailure)
{
    CV *cv;
    GV *gv;
    HV *stash = (HV *)NULL;
    char *handler_name = "handler";
    char *tmp;

    if (MpHandlerANON(handler)) {
        /* already resolved anonymous handler */
        return 1;
    }

    if (strnEQ(name, "sub ", 4)) {
        SV *sv;
        CV *cv;
        MpHandlerPARSED_On(handler);
        MpHandlerANON_On(handler);

        ENTER;SAVETMPS;
        sv = eval_pv(name, TRUE);
        if (!(SvROK(sv) && (cv = (CV*)SvRV(sv)) && (CvFLAGS(cv) & CVf_ANON))) {

            Perl_croak(aTHX_ "expected anonymous sub, got '%s'\n", name);
        }

#ifdef USE_ITHREADS
        handler->cv      = NULL;
        handler->name    = NULL;
        handler->mgv_obj = modperl_handler_anon_next(aTHX_ p);
        modperl_handler_anon_add(aTHX_ handler->mgv_obj, cv);
        MP_TRACE_h(MP_FUNC, "new anon handler");
#else
        SvREFCNT_inc(cv);
        handler->cv      = cv;
        handler->name    = NULL;
        MP_TRACE_h(MP_FUNC, "new cached-cv anon handler");
#endif

        FREETMPS;LEAVE;

        return 1;
    }

    if ((tmp = strstr((char *)name, "->"))) {
        int package_len = strlen(name) - strlen(tmp);
        char *package = apr_pstrndup(p, name, package_len);

        name = package;
        handler_name = &tmp[2];

        MpHandlerMETHOD_On(handler);

        if (*package == '$') {
            GV *gv;
            SV *obj;

            handler->mgv_obj = modperl_mgv_compile(aTHX_ p, package + 1);
            gv = modperl_mgv_lookup(aTHX_ handler->mgv_obj);
            obj = gv ? GvSV(gv) : (SV *)NULL;

            if (SvTRUE(obj)) {
                if (SvROK(obj) && sv_isobject(obj)) {
                    stash = SvSTASH(SvRV(obj));
                    MpHandlerOBJECT_On(handler);
                    MP_TRACE_h(MP_FUNC, "handler object %s isa %s",
                               package, HvNAME(stash));
                }
                else {
                    MP_TRACE_h(MP_FUNC, "%s is not an object, pv=%s",
                               package, SvPV_nolen(obj));
                    return 0;
                }
            }
            else {
                MP_TRACE_h(MP_FUNC, "failed to thaw %s", package);
                return 0;
            }
        }

        if (!stash) {
            if ((stash = gv_stashpvn(package, package_len, FALSE))) {
                MP_TRACE_h(MP_FUNC, "handler method %s isa %s",
                           name, HvNAME(stash));
            }
        }
    }
    else {
        if ((cv = get_cv(name, FALSE))) {
            handler->attrs = *modperl_code_attrs(aTHX_ cv);
            handler->mgv_cv =
                modperl_mgv_compile(aTHX_ p, HvNAME(GvSTASH(CvGV(cv))));
            modperl_mgv_append(aTHX_ p, handler->mgv_cv, GvNAME(CvGV(cv)));
            MpHandlerPARSED_On(handler);
            MODPERL_MGV_DEEP_RESOLVE(handler, p);
            return 1;
        }
    }

    if (!stash && MpHandlerAUTOLOAD(handler)) {
        if (!modperl_perl_module_loaded(aTHX_ name)) { /* not in %INC */
            MP_TRACE_h(MP_FUNC,
                       "package %s not in %INC, attempting to load it",
                       name);

            if (modperl_require_module(aTHX_ name, logfailure)) {
                MP_TRACE_h(MP_FUNC, "loaded %s package", name);
            }
            else {
                if (logfailure) {
                    /* the caller doesn't handle the error checking */
                    Perl_croak(aTHX_ "failed to load %s package\n", name);
                }
                else {
                    /* the caller handles the error checking */
                    MP_TRACE_h(MP_FUNC, "failed to load %s package", name);
                    return 0;
                }
            }
        }
        else {
            MP_TRACE_h(MP_FUNC, "package %s seems to be loaded", name);
        }
    }

    /* try to lookup the stash only after loading the module, to avoid
     * the case where a stash is autovivified by a user before the
     * module was loaded, preventing from loading the module
     */
    if (!(stash || (stash = gv_stashpv(name, FALSE)))) {
        MP_TRACE_h(MP_FUNC, "%s's stash is not found", name);
        return 0;
    }

    if ((gv = gv_fetchmethod(stash, handler_name)) && (cv = GvCV(gv))) {
        if (CvFLAGS(cv) & CVf_METHOD) { /* sub foo : method {}; */
            MpHandlerMETHOD_On(handler);
        }

        if (!stash) {
            return 0;
        }


        if (MpHandlerMETHOD(handler) && !handler->mgv_obj) {
            char *name = HvNAME(stash);
            if (!name) {
                name = "";
            }
            modperl_mgv_new_name(handler->mgv_obj, p, name);
        }

        handler->attrs = *modperl_code_attrs(aTHX_ cv);
        /* note: this is the real function after @ISA lookup */
        handler->mgv_cv = modperl_mgv_compile(aTHX_ p, HvNAME(GvSTASH(gv)));
        modperl_mgv_append(aTHX_ p, handler->mgv_cv, handler_name);

        MpHandlerPARSED_On(handler);
        MP_TRACE_h(MP_FUNC, "found `%s' in class `%s' as a %s",
                   handler_name, HvNAME(stash),
                   MpHandlerMETHOD(handler) ? "method" : "function");
        MODPERL_MGV_DEEP_RESOLVE(handler, p);
        return 1;
    }

    /* at least modperl_hash_handlers needs to verify that an
     * autoloaded-marked handler needs to be loaded, since it doesn't
     * check success failure, and handlers marked to be autoloaded are
     * the same as PerlModule and the failure should be fatal */
    if (MpHandlerAUTOLOAD(handler)) {
        Perl_croak(aTHX_ "failed to resolve handler %s\n", name);
    }

#ifdef MP_TRACE
    /* complain only if the class was actually loaded/created */
    if (stash) {
        MP_TRACE_h(MP_FUNC, "`%s' not found in class `%s'",
                   handler_name, name);
    }
#endif

    return 0;
}

modperl_mgv_t *modperl_mgv_last(modperl_mgv_t *symbol)
{
    while (symbol->next) {
        symbol = symbol->next;
    }

    return symbol;
}

char *modperl_mgv_last_name(modperl_mgv_t *symbol)
{
    symbol = modperl_mgv_last(symbol);
    return symbol->name;
}

char *modperl_mgv_as_string(pTHX_ modperl_mgv_t *symbol,
                            apr_pool_t *p, int package)
{
    char *string, *ptr;
    modperl_mgv_t *mgv;
    int len = 0;

    for (mgv = symbol; (package ? mgv->next : mgv); mgv = mgv->next) {
        len += mgv->len;
    }

    ptr = string = apr_palloc(p, len+1);

    for (mgv = symbol; (package ? mgv->next : mgv); mgv = mgv->next) {
        Copy(mgv->name, ptr, mgv->len, char);
        ptr += mgv->len;
    }

    if (package) {
        *(ptr-2) = '\0'; /* trim trailing :: */
    }
    else {
        *ptr = '\0';
    }

    return string;
}

#ifdef USE_ITHREADS
int modperl_mgv_require_module(pTHX_ modperl_mgv_t *symbol,
                               server_rec *s, apr_pool_t *p)
{
    char *package =
        modperl_mgv_as_string(aTHX_ symbol, p, 1);

    if (modperl_require_module(aTHX_ package, TRUE)) {
        MP_TRACE_h(MP_FUNC, "reloaded %s for server %s",
                   package, modperl_server_desc(s, p));
        return TRUE;
    }

    return FALSE;
}
#endif

/* precompute the hash(es) for handler names, preload handlers
 * configured to be autoloaded */
static void modperl_hash_handlers(pTHX_ apr_pool_t *p, server_rec *s,
                                  MpAV *entry, void *data)
{
    MP_dSCFG(s);
    int i;
    modperl_handler_t **handlers;

    if (!entry) {
        return;
    }

    handlers = (modperl_handler_t **)entry->elts;

    for (i=0; i < entry->nelts; i++) {
        modperl_handler_t *handler = handlers[i];

        if (MpHandlerFAKE(handler)) {
            /* do nothing with fake handlers */
        }
        else if (MpHandlerPARSED(handler)) {
#ifdef USE_ITHREADS
            if ((MpSrvPARENT(scfg) && MpSrvAUTOLOAD(scfg))
                && !modperl_mgv_lookup(aTHX_ handler->mgv_cv)) {
                /*
                 * this VirtualHost has its own parent interpreter
                 * must require the module again with this server's THX
                 */
                modperl_mgv_require_module(aTHX_ handler->mgv_cv,
                                           s, p);
            }
#endif
            MP_TRACE_h(MP_FUNC, "%s already resolved in server %s",
                       modperl_handler_name(handler),
                       modperl_server_desc(s, p));
        }
        else {
            if (MpSrvAUTOLOAD(scfg)) {
                MpHandlerAUTOLOAD_On(handler);
            }

            modperl_mgv_resolve(aTHX_ handler, p, handler->name, TRUE);
        }
    }
}

static int modperl_hash_handlers_dir(apr_pool_t *p, server_rec *s,
                                     void *cfg, char *d, void *data)
{
    int i;
    modperl_config_dir_t *dir_cfg = (modperl_config_dir_t *)cfg;
    dTHXa(data);

    if (!dir_cfg) {
        return 1;
    }

    for (i=0; i < MP_HANDLER_NUM_PER_DIR; i++) {
        modperl_hash_handlers(aTHX_ p, s, dir_cfg->handlers_per_dir[i], data);
    }

    return 1;
}

static int modperl_hash_handlers_srv(apr_pool_t *p, server_rec *s,
                                     void *cfg, void *data)
{
    int i;
    modperl_config_srv_t *scfg = (modperl_config_srv_t *)cfg;
    dTHXa(data);

    for (i=0; i < MP_HANDLER_NUM_PER_SRV; i++) {
        modperl_hash_handlers(aTHX_ p, s,
                              scfg->handlers_per_srv[i], data);
    }

    for (i=0; i < MP_HANDLER_NUM_PROCESS; i++) {
        modperl_hash_handlers(aTHX_ p, s,
                              scfg->handlers_process[i], data);
    }

    for (i=0; i < MP_HANDLER_NUM_CONNECTION; i++) {
        modperl_hash_handlers(aTHX_ p, s,
                              scfg->handlers_connection[i], data);
    }

    for (i=0; i < MP_HANDLER_NUM_FILES; i++) {
        modperl_hash_handlers(aTHX_ p, s,
                              scfg->handlers_files[i], data);
    }

    return 1;
}

void modperl_mgv_hash_handlers(apr_pool_t *p, server_rec *s)
{
    MP_dINTERPa(NULL, NULL, s);
    ap_pcw_walk_config(p, s, &perl_module,
#ifdef USE_ITHREADS
                       aTHX,
#else
                       NULL,
#endif
                       modperl_hash_handlers_dir,
                       modperl_hash_handlers_srv);
    MP_INTERP_PUTBACK(interp, aTHX);
}

/*
 * Local Variables:
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * End:
 */
