/* 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.
 */

/*
 *
 * @author Mladen Turk
 * @version $Revision$, $Date$
 */
 
#include "tcn.h"
#include "apr_thread_proc.h"
#include "apr_version.h"

#define ERRFN_USERDATA_KEY    "TCNATIVECHILDERRFN"

static void generic_child_errfn(apr_pool_t *pool, apr_status_t err,
                                const char *description)
{
    void *data;
    tcn_callback_t *cb;

    apr_pool_userdata_get(&data, ERRFN_USERDATA_KEY, pool);
    cb = (tcn_callback_t *)data;
    if (cb) {
        JNIEnv *env;
        tcn_get_java_env(&env);
        if (!TCN_IS_NULL(env, cb->obj)) {
            (*(env))->CallVoidMethod(env, cb->obj, cb->mid[0],
                                P2J(pool), (jint)err,
                                (*(env))->NewStringUTF(env, description),
                                NULL);
        }
    }
}

static apr_status_t child_errfn_pool_cleanup(void *data)
{
    tcn_callback_t *cb = (tcn_callback_t *)data;

    if (data) {
        JNIEnv *env;
        tcn_get_java_env(&env);
        if (!TCN_IS_NULL(env, cb->obj)) {
            TCN_UNLOAD_CLASS(env, cb->obj);
        }
        free(cb);
    }
    return APR_SUCCESS;
}

TCN_IMPLEMENT_CALL(jlong, Procattr, create)(TCN_STDARGS,
                                            jlong pool)
{
    apr_pool_t *p = J2P(pool, apr_pool_t *);
    apr_procattr_t *attr;


    UNREFERENCED(o);
    TCN_THROW_IF_ERR(apr_procattr_create(&attr, p), attr);

cleanup:
    return P2J(attr);
}

TCN_IMPLEMENT_CALL(jint, Procattr, ioSet)(TCN_STDARGS,
                                          jlong attr, jint in,
                                          jint out, jint err)
{
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);

    UNREFERENCED_STDARGS;
    return (jint)apr_procattr_io_set(a, (apr_int32_t)in,
                     (apr_int32_t)out, (apr_int32_t)err);
}

TCN_IMPLEMENT_CALL(jint, Procattr, childInSet)(TCN_STDARGS,
                                          jlong attr, jlong in,
                                          jlong parent)
{
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);
    apr_file_t *f = J2P(in, apr_file_t *);
    apr_file_t *p = J2P(parent, apr_file_t *);

    UNREFERENCED_STDARGS;
    return (jint)apr_procattr_child_in_set(a, f, p);
}

TCN_IMPLEMENT_CALL(jint, Procattr, childOutSet)(TCN_STDARGS,
                                          jlong attr, jlong out,
                                          jlong parent)
{
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);
    apr_file_t *f = J2P(out, apr_file_t *);
    apr_file_t *p = J2P(parent, apr_file_t *);

    UNREFERENCED_STDARGS;
    return (jint)apr_procattr_child_out_set(a, f, p);
}

TCN_IMPLEMENT_CALL(jint, Procattr, childErrSet)(TCN_STDARGS,
                                          jlong attr, jlong err,
                                          jlong parent)
{
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);
    apr_file_t *f = J2P(err, apr_file_t *);
    apr_file_t *p = J2P(parent, apr_file_t *);

    UNREFERENCED_STDARGS;
    return (jint)apr_procattr_child_in_set(a, f, p);
}

TCN_IMPLEMENT_CALL(jint, Procattr, dirSet)(TCN_STDARGS,
                                           jlong attr,
                                           jstring dir)
{
    apr_status_t rv;
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);
    TCN_ALLOC_CSTRING(dir);

    UNREFERENCED(o);

    rv = apr_procattr_dir_set(a, J2S(dir));
    TCN_FREE_CSTRING(dir);
    return (jint) rv;
}

TCN_IMPLEMENT_CALL(jint, Procattr, cmdtypeSet)(TCN_STDARGS,
                                          jlong attr, jint cmd)
{
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);

    UNREFERENCED_STDARGS;
    return (jint)apr_procattr_cmdtype_set(a, (apr_int32_t)cmd);
}

TCN_IMPLEMENT_CALL(jint, Procattr, detachSet)(TCN_STDARGS,
                                          jlong attr, jint detach)
{
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);

    UNREFERENCED_STDARGS;
    return (jint)apr_procattr_detach_set(a, (apr_int32_t)detach);
}

TCN_IMPLEMENT_CALL(jint, Procattr, errorCheckSet)(TCN_STDARGS,
                                          jlong attr, jint chk)
{
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);

    UNREFERENCED_STDARGS;
    return (jint)apr_procattr_error_check_set(a, (apr_int32_t)chk);
}

TCN_IMPLEMENT_CALL(jint, Procattr, addrspaceSet)(TCN_STDARGS,
                                          jlong attr, jint addr)
{
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);

    UNREFERENCED_STDARGS;
    return (jint)apr_procattr_addrspace_set(a, (apr_int32_t)addr);
}

TCN_IMPLEMENT_CALL(jlong, Proc, alloc)(TCN_STDARGS,
                                       jlong pool)
{
    apr_pool_t *p = J2P(pool, apr_pool_t *);
    apr_proc_t *proc;

    UNREFERENCED_STDARGS;
    proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t));

    return P2J(proc);
}

#define MAX_ARGS_SIZE 1024
#define MAX_ENV_SIZE  1024

TCN_IMPLEMENT_CALL(jint, Proc, create)(TCN_STDARGS, jlong proc,
                                       jstring progname,
                                       jobjectArray args,
                                       jobjectArray env,
                                       jlong attr, jlong pool)
{
    apr_status_t rv;
    apr_pool_t *p = J2P(pool, apr_pool_t *);
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);
    apr_proc_t *np = J2P(proc, apr_proc_t *);
    TCN_ALLOC_CSTRING(progname);
    char *s_args[MAX_ARGS_SIZE];
    char *s_env[MAX_ENV_SIZE];
    const char * const *pargs = NULL;
    const char * const *penv  = NULL;
    jsize as = 0;
    jsize es = 0;
    jsize i;

    UNREFERENCED(o);
    if (args)
        as = (*e)->GetArrayLength(e, args);
    if (env)
        es = (*e)->GetArrayLength(e, args);
    if (as > (MAX_ARGS_SIZE - 1) || es > (MAX_ENV_SIZE - 2)) {
        TCN_FREE_CSTRING(progname);
        return APR_EINVAL;
    }
    if (as) {
        for (i = 0; i < as; i++) {
            jstring str = (*e)->GetObjectArrayElement(e, args, i);
            s_args[i] = tcn_get_string(e, str);
            (*e)->DeleteLocalRef(e, str);
        }
        s_args[i] = NULL;
        pargs = (const char * const *)&s_args[0];
    }
    if (es) {
        for (i = 0; i < es; i++) {
            jstring str = (*e)->GetObjectArrayElement(e, env, i);
            s_env[i+1] = tcn_get_string(e, str);
            (*e)->DeleteLocalRef(e, str);
        }
#ifdef WIN32
        s_env[i++] = apr_psprintf(p, TCN_PARENT_IDE "=%d", getpid());
#endif
        s_env[i] = NULL;
        penv = (const char * const *)&s_env[0];
    }
#ifdef WIN32
    else {
        char pps[32];
        itoa(getpid(), pps, 10);
        SetEnvironmentVariable(TCN_PARENT_IDE, pps);
    }
#endif
    rv = apr_proc_create(np, J2S(progname), pargs,
                         penv, a, p);
#ifdef WIN32
    if (!es)
        SetEnvironmentVariable(TCN_PARENT_IDE, NULL);
#endif

    /* Free local resources */
    TCN_FREE_CSTRING(progname);
    for (i = 0; i < as; i++) {
        if (s_args[i])
            free(s_args[i]);
    }
    for (i = 0; i < es; i++) {
        if (s_env[i])
            free(s_env[i]);
    }
    return rv;
}

TCN_IMPLEMENT_CALL(jint, Proc, wait)(TCN_STDARGS, jlong proc,
                                     jintArray rvals, jint waithow)
{
    apr_status_t rv;
    apr_proc_t *p = J2P(proc, apr_proc_t *);
    int exitcode;
    apr_exit_why_e exitwhy;

    UNREFERENCED(o);

    rv = apr_proc_wait(p, &exitcode, &exitwhy, (apr_wait_how_e)waithow);
    if (rv == APR_SUCCESS && rvals) {
        jsize n = (*e)->GetArrayLength(e, rvals);
        if (n > 1) {
            jint *ints = (*e)->GetIntArrayElements(e, rvals, NULL);
            ints[0] = exitcode;
            ints[1] = exitwhy;
            (*e)->ReleaseIntArrayElements(e, rvals, ints, 0);
        }
    }
    return rv;
}

TCN_IMPLEMENT_CALL(jint, Proc, waitAllProcs)(TCN_STDARGS,
                                             jlong proc, jintArray rvals,
                                             jint waithow, jlong pool)
{
    apr_status_t rv;
    apr_proc_t *p = J2P(proc, apr_proc_t *);
    apr_pool_t *c = J2P(pool, apr_pool_t *);
    int exitcode;
    apr_exit_why_e exitwhy;

    UNREFERENCED(o);

    rv = apr_proc_wait_all_procs(p, &exitcode, &exitwhy,
                                 (apr_wait_how_e)waithow, c);
    if (rv == APR_SUCCESS && rvals) {
        jsize n = (*e)->GetArrayLength(e, rvals);
        if (n > 1) {
            jint *ints = (*e)->GetIntArrayElements(e, rvals, NULL);
            ints[0] = exitcode;
            ints[1] = exitwhy;
            (*e)->ReleaseIntArrayElements(e, rvals, ints, 0);
        }
    }
    return rv;
}

TCN_IMPLEMENT_CALL(jint, Proc, detach)(TCN_STDARGS, jint daemonize)
{

    UNREFERENCED_STDARGS;
#if defined(WIN32) || defined (NETWARE)
    UNREFERENCED(daemonize);
    return APR_ENOTIMPL;
#else
    return (jint)apr_proc_detach(daemonize);
#endif
}

TCN_IMPLEMENT_CALL(jint, Proc, kill)(TCN_STDARGS, jlong proc, jint sig)
{
    apr_proc_t *p = J2P(proc, apr_proc_t *);

    UNREFERENCED_STDARGS;
    return (jint)apr_proc_kill(p, (int)sig);
}

TCN_IMPLEMENT_CALL(void, Pool, noteSubprocess)(TCN_STDARGS, jlong pool,
                                               jlong proc, jint how)
{
    apr_proc_t *p = J2P(proc, apr_proc_t *);
    apr_pool_t *a = J2P(pool, apr_pool_t *);

    UNREFERENCED_STDARGS;
    apr_pool_note_subprocess(a, p, (apr_kill_conditions_e)how);
}

TCN_IMPLEMENT_CALL(jint, Proc, fork)(TCN_STDARGS,
                                     jlongArray proc,
                                     jlong pool)
{
    apr_status_t rv = APR_EINVAL;

#if APR_HAS_FORK
    apr_pool_t *p = J2P(pool, apr_pool_t *);
    apr_proc_t *f = apr_pcalloc(p, sizeof(apr_proc_t));

    UNREFERENCED(o);

    rv = apr_proc_fork(f, p);
    if (rv == APR_SUCCESS && proc) {
        jsize n = (*e)->GetArrayLength(e, proc);
        if (n > 0) {
            jlong *rp = (*e)->GetLongArrayElements(e, proc, NULL);
            rp[0] = P2J(f);
            (*e)->ReleaseLongArrayElements(e, proc, rp, 0);
        }
    }
#else
    UNREFERENCED_STDARGS;
    UNREFERENCED(proc);
    UNREFERENCED(pool);

#endif
    return rv;
}

TCN_IMPLEMENT_CALL(void, Procattr, errfnSet)(TCN_STDARGS, jlong attr,
                                             jlong pool, jobject obj)
{
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);
    apr_pool_t *p = J2P(pool, apr_pool_t *);
    tcn_callback_t *cb = (tcn_callback_t *)malloc(sizeof(tcn_callback_t));
    jclass cls;

    UNREFERENCED(o);

    if (cb == NULL) {
       return;
    }
    cls = (*e)->GetObjectClass(e, obj);
    cb->obj    = (*e)->NewGlobalRef(e, obj);
    cb->mid[0] = (*e)->GetMethodID(e, cls, "callback", "(JILjava/lang/String;)V");

    apr_pool_userdata_setn(cb, ERRFN_USERDATA_KEY, child_errfn_pool_cleanup, p);
    apr_procattr_child_errfn_set(a, generic_child_errfn);

}

TCN_IMPLEMENT_CALL(jint, Procattr, userSet)(TCN_STDARGS,
                                            jlong attr,
                                            jstring username,
                                            jstring password)
{

#if ((APR_MAJOR_VERSION >= 1) && (APR_MINOR_VERSION >= 1))
    apr_status_t rv;
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);
    TCN_ALLOC_CSTRING(username);
#if APR_PROCATTR_USER_SET_REQUIRES_PASSWORD
    TCN_ALLOC_CSTRING(password);
#else
    const char *cpassword = NULL;
#endif
    UNREFERENCED(o);

    rv = apr_procattr_user_set(a, J2S(username), J2S(password));
    TCN_FREE_CSTRING(username);
#if APR_PROCATTR_USER_SET_REQUIRES_PASSWORD
    TCN_FREE_CSTRING(password);
#endif
    return (jint) rv;
#else
    UNREFERENCED_STDARGS;
    UNREFERENCED(attr);
    UNREFERENCED(username);
    UNREFERENCED(password);

    return APR_ENOTIMPL;
#endif
}

TCN_IMPLEMENT_CALL(jint, Procattr, groupSet)(TCN_STDARGS,
                                             jlong attr,
                                             jstring group)
{

#if ((APR_MAJOR_VERSION >= 1) && (APR_MINOR_VERSION >= 1))
    apr_status_t rv;
    apr_procattr_t *a = J2P(attr, apr_procattr_t *);
    TCN_ALLOC_CSTRING(group);

    UNREFERENCED(o);

    rv = apr_procattr_group_set(a, J2S(group));
    TCN_FREE_CSTRING(group);
    return (jint) rv;
#else
    UNREFERENCED_STDARGS;
    UNREFERENCED(attr);
    UNREFERENCED(group);

    return APR_ENOTIMPL;
#endif
}
