/*
 *  Copyright 1999-2004 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.
 */

/*
 * Module jk2: keeps all servlet/jakarta related ramblings together.
 *
 * Author: Alexander Leykekh (aolserver@aol.net)
 *
 */


#include "ns.h"
#include "jk_ns.h"
#include <jni.h>

#define LOG_ERROR(msg) Ns_Log(Error,"nsjk2: %s:%d:$s",__FILE__,__LINE__,msg)
#define LOG_ERROR2(msg1,msg2) Ns_Log(Error,"nsjk2: %s:%d:$s:%s",__FILE__,__LINE__,msg1,msg2)

/* Context allows request handler extract worker and vhost for the URI quickly */
typedef struct {
    char* serverName;
    jk_uriEnv_t* uriEnv;
} uriContext;
  

#ifdef WIN32
static char  file_name[_MAX_PATH];
#endif


/* Standard AOLserver module global */
int Ns_ModuleVersion = 1;

/* Globals 
 *
 * There is one instance of JVM worker environment per process, regardless of 
 * virtual servers in AOLserver's nsd.tcl file or their counterparts in
 * Tomcat's server.xml. The only thing that AOLserver virtual servers do separately
 * is map URIs for Tomcat to process.
 *
 */
static jk_workerEnv_t *workerEnv = NULL; /* JK2 environment */
static JavaVM* jvmGlobal = NULL; /* JVM instance */
static Ns_Tls jkTls; /* TLS destructor detaches request thread from JVM */
static unsigned jkInitCount =0; /* number of running virtual servers using this module */

/** Basic initialization for jk2.
 */
static int jk2_create_workerEnv(apr_pool_t *p, char* serverRoot) {
    jk_env_t *env;
    jk_logger_t *l;
    jk_pool_t *globalPool;
    jk_bean_t *jkb;
    
    if (jk2_pool_apr_create( NULL, &globalPool, NULL, p) != JK_OK) {
        LOG_ERROR("Cannot create apr pool");
	return JK_ERR;
    }

    /** Create the global environment. This will register the default
        factories
    */
    env=jk2_env_getEnv( NULL, globalPool );
    if (env == NULL) {
        LOG_ERROR("jk2_create_workerEnv: Cannot get environment");
	return JK_ERR;
    }
        
    /* Optional. Register more factories ( or replace existing ones ) */
    /* Init the environment. */
    
    /* Create the logger */
    env->registerFactory( env, "logger.ns",  jk2_logger_ns_factory );

    jkb=env->createBean2( env, env->globalPool, "logger.ns", "");
    if (jkb == NULL) {
        LOG_ERROR("Cannot create logger bean (with factory)");
	return JK_ERR;
    }

    env->alias( env, "logger.ns:", "logger");
    l = jkb->object;
    env->l=l;
    
#ifdef WIN32
    env->soName=env->globalPool->pstrdup(env, env->globalPool, file_name);
    
    if( env->soName == NULL ){
        env->l->jkLog(env, env->l, JK_LOG_ERROR, "Error creating env->soName\n");
        return JK_ERR;
    }
#else 
    env->soName=NULL;
#endif
    
    /* Create the workerEnv */
    jkb=env->createBean2( env, env->globalPool,"workerEnv", "");
    if (jkb == NULL) {
        LOG_ERROR("Cannot create worker environment bean");
	return JK_ERR;
    }

    workerEnv= jkb->object;

    if( workerEnv==NULL ) {
        env->l->jkLog(env, env->l, JK_LOG_ERROR, "Error creating workerEnv\n");
        return JK_ERR;
    }

    env->alias( env, "workerEnv:" , "workerEnv");

    /* AOLserver is a single-process environment, but leaving childId as -1 breaks
       JNI initialization
    */
    workerEnv->childId=0;
    
    workerEnv->initData->add( env, workerEnv->initData, "serverRoot",
                              workerEnv->pool->pstrdup( env, workerEnv->pool, serverRoot));

    env->l->jkLog(env, env->l, JK_LOG_INFO, "Set JK2 serverRoot %s\n", serverRoot);
    
    return JK_OK;
}


/**
 * Shutdown callback for AOLserver
 */
void jk2_shutdown_system (void* data)
{
    if (--jkInitCount == 0) {

	apr_pool_terminate ();
	apr_terminate ();
    }
}    


/**
 * JK2 module shutdown callback for APR (Apache Portable Runtime)
 */
static apr_status_t jk2_shutdown(void *data)
{
    jk_env_t *env;
    if (workerEnv) {
        env=workerEnv->globalEnv;
        /* bug in APR?? results in SEGV. Not important, the process is going away

	workerEnv->close(env, workerEnv);
	*/

	if( workerEnv->vm != NULL  && !workerEnv->vm->mbean->disabled)
	    workerEnv->vm->destroy( env, workerEnv->vm );

        workerEnv = NULL;
    }
    return APR_SUCCESS;
}


/* ========================================================================= */
/* The JK module handlers                                                    */
/* ========================================================================= */

/** Main service method, called to forward a request to tomcat
 */
static int jk2_handler(void* context, Ns_Conn *conn)
{   
    jk_logger_t      *l=NULL;
    int              rc;
    jk_worker_t *worker=NULL;
    jk_endpoint_t *end = NULL;
    jk_env_t *env;
    char* workerName;
    jk_ws_service_t *s=NULL;
    jk_pool_t *rPool=NULL;
    int rc1;
    jk_uriEnv_t *uriEnv;
    uriContext* uriCtx = (uriContext*)context;


    /* must make this call to assure TLS destructor runs when thread exists */
    Ns_TlsSet (&jkTls, jvmGlobal);

    uriEnv= uriCtx->uriEnv;
    /* there is a chance of dynamic reconfiguration, so instead of doing above statement, might map
       the URI to its context object on the fly, like this:

       uriEnv = workerEnv->uriMap->mapUri (workerEnv->globalEnv, workerEnv->uriMap, conn->request->host, conn->request->url);
    */

    /* Get an env instance */
    env = workerEnv->globalEnv->getEnv( workerEnv->globalEnv );

    worker = uriEnv->worker;

    if (worker == NULL) /* use global default */
        worker=workerEnv->defaultWorker;

    workerName = uriEnv->mbean->getAttribute (env, uriEnv->mbean, "group");

    if( worker==NULL && workerName!=NULL ) {
        worker=env->getByName( env, workerName);
        env->l->jkLog(env, env->l, JK_LOG_INFO, 
                      "finding worker for %#lx %#lx %s\n",
                      worker, uriEnv, workerName);
        uriEnv->worker=worker;
    }

    if(worker==NULL || worker->mbean==NULL || worker->mbean->localName==NULL ) {
        env->l->jkLog(env, env->l, JK_LOG_ERROR, 
                      "No worker for %s\n", conn->request->url); 
        workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
        return NS_FILTER_RETURN;
    }

    if( uriEnv->mbean->debug > 0 )
        env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
                      "serving %s with %#lx %#lx %s\n",
                      uriEnv->mbean->localName, worker, worker->mbean, worker->mbean->localName );

    /* Get a pool for the request */
    rPool= worker->rPoolCache->get( env, worker->rPoolCache );
    if( rPool == NULL ) {
        rPool=worker->mbean->pool->create( env, worker->mbean->pool, HUGE_POOL_SIZE );
        if( uriEnv->mbean->debug > 0 )
            env->l->jkLog(env, env->l, JK_LOG_DEBUG, "new rpool %#lx\n", rPool );
    }
    
    s=(jk_ws_service_t *)rPool->calloc( env, rPool, sizeof( jk_ws_service_t ));
    
    jk2_service_ns_init( env, s, uriCtx->serverName);
    
    s->pool = rPool;
    s->init( env, s, worker, conn );

    /* reset the reco_status, will be set to INITED in LB mode */
    s->reco_status = RECO_NONE;
    
    s->is_recoverable_error = JK_FALSE;
    s->uriEnv = uriEnv; 
    rc = worker->service(env, worker, s);    
    s->afterRequest(env, s);
    rPool->reset(env, rPool);

    rc1=worker->rPoolCache->put( env, worker->rPoolCache, rPool );

    if( rc1 == JK_OK ) {
        rPool=NULL;
    }

    if( rPool!=NULL ) {
        rPool->close(env, rPool);
    }

    if(rc==JK_OK) {
        workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
        return NS_OK;
    }

    env->l->jkLog(env, env->l, JK_LOG_ERROR, "Error connecting to tomcat %d\n", rc);
    workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
    Ns_ConnReturnInternalError (conn);
    return NS_FILTER_RETURN;
}


/*
 * TLS destructor. Sole purpose is to detach current thread from JVM before the thread exits
 */
static void jkTlsDtor (void* arg) {
    void* env = NULL;
    jint err;

    /* check if attached 1st */
    if (jvmGlobal!=NULL && 
	JNI_OK==((*jvmGlobal)->GetEnv(jvmGlobal, &env, JNI_VERSION_1_2 ))) 
        {
        (*jvmGlobal)->DetachCurrentThread (jvmGlobal);
	}
}


/** Register a URI pattern with AOLserver
 */
static void registerURI (jk_env_t* env, jk_uriEnv_t* uriEnv, char* vserver, char* serverName) {
    uriContext* ctx;
    char* uriname;

    if (uriEnv==NULL || uriEnv->mbean==NULL)
	return;

    uriname=uriEnv->mbean->getAttribute (env, uriEnv->mbean, "uri");
    if (uriname==NULL || strcmp(uriname, "/")==0)
        return;

    ctx = Ns_Malloc (sizeof (uriContext));
    if (ctx == NULL)
        return;

    ctx->serverName = serverName;
    ctx->uriEnv = uriEnv;

    if (uriEnv->mbean->debug > 0)
        env->l->jkLog (env, env->l, JK_LOG_DEBUG, "registering URI %s", uriname);

    Ns_RegisterRequest(vserver, "GET", uriname, jk2_handler, NULL, ctx, 0);
    Ns_RegisterRequest(vserver, "HEAD", uriname, jk2_handler, NULL, ctx, 0);
    Ns_RegisterRequest(vserver, "POST", uriname, jk2_handler, NULL, ctx, 0);
}


/** Standard AOLserver callback.
 * Initialize jk2, unless already done in another server. Register URI mappping for Tomcat
 * If multiple virtual servers use this module, calls to Ns_ModuleInit will be made serially
 * in order of appearance of those servers in nsd.tcl
 */
int Ns_ModuleInit(char *server, char *module)
{
    jk_env_t *env;
    
    /* configuration-related */
    char* serverName=NULL;
    char* confPath;
    static char cwdBuf[PATH_MAX];
    static char* serverRoot = NULL;

    /* APR-related */
    apr_status_t aprrc;
    char errbuf[512];
    apr_pool_t *jk_globalPool = NULL;

    /* URI registration */
    char *hosts[2] = {"*", NULL};
    jk_map_t *vhosts;
    int i, j, k, l, cnt1, cnt2;
    jk_map_t *uriMap, *webapps, *uriMaps[3];
    jk_uriEnv_t *uriEnv, *hostEnv, *appEnv;


    if (jkInitCount++ == 0) {

        /* Get Tomcat installation root - this value is same for all virtual servers*/
        if (serverRoot == NULL) {
            confPath = Ns_ConfigGetPath (NULL, module, NULL);
            serverRoot = (confPath? Ns_ConfigGetValue (confPath, "serverRoot") : NULL);
        }

        /* not configured in nsd.tcl? try env. variable */
        if (serverRoot == NULL) {
            serverRoot = getenv ("TOMCAT_HOME");
        }

        /* not in env. variables? get it from CWD */
        if (serverRoot == NULL) {
            serverRoot = getcwd (cwdBuf, sizeof(cwdBuf));
        }

	/* Initialize APR */
	if ((aprrc=apr_initialize()) != APR_SUCCESS) {
	    LOG_ERROR2 ("Cannot initialize APR", apr_strerror (aprrc, errbuf, sizeof(errbuf)));
	    return NS_ERROR;
	}

	if ((aprrc=apr_pool_create(&jk_globalPool, NULL)) != APR_SUCCESS) {
	    LOG_ERROR2 ("Cannot create global APR pool", apr_strerror (aprrc, errbuf, sizeof(errbuf)));
	    return NS_ERROR;
	}

	/* Initialize JNI */
	if (workerEnv==NULL && jk2_create_workerEnv(jk_globalPool, serverRoot)==JK_ERR) {
	    return NS_ERROR;
	}

	env=workerEnv->globalEnv;
	env->setAprPool(env, jk_globalPool);

	/* Initialize JK2 */
	if (workerEnv->init(env, workerEnv ) != JK_OK) {
	    LOG_ERROR("Cannot initialize worker environment");
	    return NS_ERROR;
	}

	workerEnv->server_name = apr_pstrcat (jk_globalPool, Ns_InfoServerName(), " ", Ns_InfoServerVersion (), NULL);
	apr_pool_cleanup_register(jk_globalPool, NULL, jk2_shutdown, apr_pool_cleanup_null);

	workerEnv->was_initialized = JK_TRUE; 
    
	if ((aprrc=apr_pool_userdata_set( "INITOK", "Ns_ModuleInit", NULL, jk_globalPool )) != APR_SUCCESS) {
	    LOG_ERROR2 ("Cannot set APR pool user data", apr_strerror (aprrc, errbuf, sizeof(errbuf)));
	    return NS_ERROR;
	}

	if (workerEnv->parentInit( env, workerEnv) != JK_OK) {
	    LOG_ERROR ("Cannot initialize global environment");
	    return NS_ERROR;
	}

	/* Obtain TLS slot - it's destructor will detach threads from JVM */
	jvmGlobal = workerEnv->vm->jvm;
	Ns_TlsAlloc (&jkTls, jkTlsDtor);

	Ns_Log (Notice, "nsjk2: Initialized JK2 environment");

    } else {
      
      env = workerEnv->globalEnv;
    }

    Ns_RegisterShutdown (jk2_shutdown_system, NULL);

    /* Register URI patterns from workers2.properties with AOLserver 
     *  
     * Worker environment has a list of vhosts, including "*" vhost.
     * Each vhost has a list of web applications (contexts) associated with it.
     * Each webapp has a list of exact, prefix, suffix and regexp URI patterns.
     *
     * Will register URIs that are either in vhost "*", or one with name matching
     * this AOLserver virtual server. Will ignore regexp patterns. Will register 
     * exact webapp URIs (context root) as JK2 somehow doesn't include them in URI
     * maps, even if specified in workers2.properties.
     *
     */

    /* virtual server name override if specified */
    confPath = Ns_ConfigGetPath (server, module, NULL);
    if (confPath != NULL)
        serverName = Ns_ConfigGetValue (confPath, "serverName");

    if (serverName == NULL)
        serverName = server;
    
    vhosts=workerEnv->uriMap->vhosts;
    hosts[1]= serverName;

    for (i=0; i<sizeof(hosts)/sizeof(*hosts); i++) {
        hostEnv=vhosts->get (env, vhosts, hosts[i]);

	if (hostEnv==NULL || hostEnv->webapps==NULL)
	    continue;

	webapps=hostEnv->webapps;
	cnt1=webapps->size(env, webapps);

	for (j=0; j<cnt1; j++) {
	    appEnv = webapps->valueAt (env, webapps, j);
	    if (appEnv == NULL)
	        continue;

	    /* register webapp root - registerURI checks if it is "/" */
	    registerURI (env, appEnv, server, serverName);
	    
	    uriMaps[0] = appEnv->exactMatch;
	    uriMaps[1] = appEnv->prefixMatch;
	    uriMaps[2] = appEnv->suffixMatch;

	    for (k=0; k<sizeof(uriMaps)/sizeof(*uriMaps); k++) {
	        if (uriMaps[k] == NULL)
		    continue;

	        cnt2 = uriMaps[k]->size (env, uriMaps[k]);
		
		for (l=0; l<cnt2; l++) {
		     registerURI (env, uriMaps[k]->valueAt (env, uriMaps[k], l), server, serverName);
		}
	    }
	}
    }

    Ns_Log (Notice, "nsjk2: Initialized on %s", server);

    return NS_OK;
}



#ifdef WIN32

BOOL WINAPI DllMain(HINSTANCE hInst,        // Instance Handle of the DLL
                    ULONG ulReason,         // Reason why NT called this DLL
                    LPVOID lpReserved)      // Reserved parameter for future use
{
    GetModuleFileName( hInst, file_name, sizeof(file_name));
    return TRUE;
}


#endif
