/*
 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "util.h"
#include "transport.h"
#include "debugLoop.h"
#include "sys.h"

static jdwpTransportEnv *transport;
static jrawMonitorID listenerLock;
static jrawMonitorID sendLock;

/*
 * data structure used for passing transport info from thread to thread
 */
typedef struct TransportInfo {
    char *name;
    jdwpTransportEnv *transport;
    char *address;
    long timeout;
} TransportInfo;

static struct jdwpTransportCallback callback = {jvmtiAllocate, jvmtiDeallocate};

/*
 * Print the last transport error
 */
static void
printLastError(jdwpTransportEnv *t, jdwpTransportError err)
{
    char  *msg;
    jbyte *utf8msg;
    jdwpTransportError rv;

    msg     = NULL;
    utf8msg = NULL;
    rv = (*t)->GetLastError(t, &msg); /* This is a platform encoded string */
    if ( msg != NULL ) {
        int len;
        int maxlen;

        /* Convert this string to UTF8 */
        len = (int)strlen(msg);
        maxlen = len+len/2+2; /* Should allow for plenty of room */
        utf8msg = (jbyte*)jvmtiAllocate(maxlen+1);
        (void)(gdata->npt->utf8FromPlatform)(gdata->npt->utf,
            msg, len, utf8msg, maxlen);
        utf8msg[maxlen] = 0;
    }
    if (rv == JDWPTRANSPORT_ERROR_NONE) {
        ERROR_MESSAGE(("transport error %d: %s",err, utf8msg));
    } else if ( msg!=NULL ) {
        ERROR_MESSAGE(("transport error %d: %s",err, utf8msg));
    } else {
        ERROR_MESSAGE(("transport error %d: %s",err, "UNKNOWN"));
    }
    jvmtiDeallocate(msg);
    jvmtiDeallocate(utf8msg);
}

/* Find OnLoad symbol */
static jdwpTransport_OnLoad_t
findTransportOnLoad(void *handle)
{
    jdwpTransport_OnLoad_t onLoad;

    onLoad = (jdwpTransport_OnLoad_t)NULL;
    if (handle == NULL) {
        return onLoad;
    }
    onLoad = (jdwpTransport_OnLoad_t)
                 dbgsysFindLibraryEntry(handle, "jdwpTransport_OnLoad");
    return onLoad;
}

/* Load transport library (directory=="" means do system search) */
static void *
loadTransportLibrary(const char *libdir, const char *name)
{
    void *handle;
    char libname[MAXPATHLEN+2];
    char buf[MAXPATHLEN*2+100];
    const char *plibdir;

    /* Convert libdir from UTF-8 to platform encoding */
    plibdir = NULL;
    if ( libdir != NULL ) {
        int  len;

        len = (int)strlen(libdir);
        (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
            (jbyte*)libdir, len, buf, (int)sizeof(buf));
        plibdir = buf;
    }

    /* Construct library name (simple name or full path) */
    dbgsysBuildLibName(libname, sizeof(libname), plibdir, name);
    if (strlen(libname) == 0) {
        return NULL;
    }

    /* dlopen (unix) / LoadLibrary (windows) the transport library */
    handle = dbgsysLoadLibrary(libname, buf, sizeof(buf));
    return handle;
}

/*
 * loadTransport() is adapted from loadJVMHelperLib() in
 * JDK 1.2 javai.c v1.61
 */
static jdwpError
loadTransport(const char *name, jdwpTransportEnv **transportPtr)
{
    JNIEnv                 *env;
    jdwpTransport_OnLoad_t  onLoad;
    void                   *handle;
    const char             *libdir;

    /* Make sure library name is not empty */
    if (name == NULL) {
        ERROR_MESSAGE(("library name is empty"));
        return JDWP_ERROR(TRANSPORT_LOAD);
    }

    /* First, look in sun.boot.library.path. This should find the standard
     *  dt_socket and dt_shmem transport libraries, or any library
     *  that was delivered with the J2SE.
     *  Note: Since 6819213 fixed, Java property sun.boot.library.path can
     *  contain multiple paths. Dll_dir is the first entry and
     *  -Dsun.boot.library.path entries are appended.
     */
    libdir = gdata->property_sun_boot_library_path;
    if (libdir == NULL) {
        ERROR_MESSAGE(("Java property sun.boot.library.path is not set"));
        return JDWP_ERROR(TRANSPORT_LOAD);
    }
    handle = loadTransportLibrary(libdir, name);
    if (handle == NULL) {
        /* Second, look along the path used by the native dlopen/LoadLibrary
         *  functions. This should effectively try and load the simple
         *  library name, which will cause the default system library
         *  search technique to happen.
         *  We should only reach here if the transport library wasn't found
         *  in the J2SE directory, e.g. it's a custom transport library
         *  not installed in the J2SE like dt_socket and dt_shmem is.
         *
         *  Note: Why not use java.library.path? Several reasons:
         *        a) This matches existing agentlib search
         *        b) These are technically not JNI libraries
         */
        handle = loadTransportLibrary("", name);
    }

    /* See if a library was found with this name */
    if (handle == NULL) {
        ERROR_MESSAGE(("transport library not found: %s", name));
        return JDWP_ERROR(TRANSPORT_LOAD);
    }

    /* Find the onLoad address */
    onLoad = findTransportOnLoad(handle);
    if (onLoad == NULL) {
        ERROR_MESSAGE(("transport library missing onLoad entry: %s", name));
        return JDWP_ERROR(TRANSPORT_LOAD);
    }

    /* Get transport interface */
    env = getEnv();
    if ( env != NULL ) {
        jdwpTransportEnv *t;
        JavaVM           *jvm;
        jint              ver;

        JNI_FUNC_PTR(env,GetJavaVM)(env, &jvm);
        ver = (*onLoad)(jvm, &callback, JDWPTRANSPORT_VERSION_1_0, &t);
        if (ver != JNI_OK) {
            switch (ver) {
                case JNI_ENOMEM :
                    ERROR_MESSAGE(("insufficient memory to complete initialization"));
                    break;

                case JNI_EVERSION :
                    ERROR_MESSAGE(("transport doesn't recognize version %x",
                        JDWPTRANSPORT_VERSION_1_0));
                    break;

                case JNI_EEXIST :
                    ERROR_MESSAGE(("transport doesn't support multiple environments"));
                    break;

                default:
                    ERROR_MESSAGE(("unrecognized error %d from transport", ver));
                    break;
            }

            return JDWP_ERROR(TRANSPORT_INIT);
        }
        *transportPtr = t;
    } else {
        return JDWP_ERROR(TRANSPORT_LOAD);
    }

    return JDWP_ERROR(NONE);
}

static void
connectionInitiated(jdwpTransportEnv *t)
{
    jint isValid = JNI_FALSE;

    debugMonitorEnter(listenerLock);

    /*
     * Don't allow a connection until initialization is complete
     */
    debugInit_waitInitComplete();

    /* Are we the first transport to get a connection? */

    if (transport == NULL) {
        transport = t;
        isValid = JNI_TRUE;
    } else {
        if (transport == t) {
            /* connected with the same transport as before */
            isValid = JNI_TRUE;
        } else {
            /*
             * Another transport got a connection - multiple transports
             * not fully supported yet so shouldn't get here.
             */
            (*t)->Close(t);
            JDI_ASSERT(JNI_FALSE);
        }
    }

    if (isValid) {
        debugMonitorNotifyAll(listenerLock);
    }

    debugMonitorExit(listenerLock);

    if (isValid) {
        debugLoop_run();
    }

}

/*
 * Set the transport property (sun.jdwp.listenerAddress) to the
 * specified value.
 */
static void
setTransportProperty(JNIEnv* env, char* value) {
    char* prop_value = (value == NULL) ? "" : value;
    setAgentPropertyValue(env, "sun.jdwp.listenerAddress", prop_value);
}

void
transport_waitForConnection(void)
{
    /*
     * If the VM is suspended on debugger initialization, we wait
     * for a connection before continuing. This ensures that all
     * events are delivered to the debugger. (We might as well do this
     * this since the VM won't continue until a remote debugger attaches
     * and resumes it.) If not suspending on initialization, we must
     * just drop any packets (i.e. events) so that the VM can continue
     * to run. The debugger may not attach until much later.
     */
    if (debugInit_suspendOnInit()) {
        debugMonitorEnter(listenerLock);
        while (transport == NULL) {
            debugMonitorWait(listenerLock);
        }
        debugMonitorExit(listenerLock);
    }
}

static void JNICALL
acceptThread(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg)
{
    TransportInfo *info;
    jdwpTransportEnv *t;
    jdwpTransportError rc;

    LOG_MISC(("Begin accept thread"));

    info = (TransportInfo*)(void*)arg;
    t = info->transport;

    rc = (*t)->Accept(t, info->timeout, 0);

    /* System property no longer needed */
    setTransportProperty(jni_env, NULL);

    if (rc != JDWPTRANSPORT_ERROR_NONE) {
        /*
         * If accept fails it probably means a timeout, or another fatal error
         * We thus exit the VM after stopping the listener.
         */
        printLastError(t, rc);
        (*t)->StopListening(t);
        EXIT_ERROR(JVMTI_ERROR_NONE, "could not connect, timeout or fatal error");
    } else {
        (*t)->StopListening(t);
        connectionInitiated(t);
    }

    LOG_MISC(("End accept thread"));
}

static void JNICALL
attachThread(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg)
{
    LOG_MISC(("Begin attach thread"));
    connectionInitiated((jdwpTransportEnv *)(void*)arg);
    LOG_MISC(("End attach thread"));
}

void
transport_initialize(void)
{
    transport = NULL;
    listenerLock = debugMonitorCreate("JDWP Transport Listener Monitor");
    sendLock = debugMonitorCreate("JDWP Transport Send Monitor");
}

void
transport_reset(void)
{
    /*
     * Reset the transport by closing any listener (will silently fail
     * with JDWPTRANSPORT_ERROR_ILLEGAL_STATE if not listening), and
     * closing any connection (will also fail silently if not
     * connected).
     *
     * Note: There's an assumption here that we don't yet support
     * multiple transports. When we do then we need a clear transition
     * from the current transport to the new transport.
     */
    if (transport != NULL) {
        setTransportProperty(getEnv(), NULL);
        (*transport)->StopListening(transport);
        (*transport)->Close(transport);
    }
}

static jdwpError
launch(char *command, char *name, char *address)
{
    jint rc;
    char *buf;
    char *commandLine;
    int  len;

    /* Construct complete command line (all in UTF-8) */
    commandLine = jvmtiAllocate((int)strlen(command) +
                                 (int)strlen(name) +
                                 (int)strlen(address) + 3);
    if (commandLine == NULL) {
        return JDWP_ERROR(OUT_OF_MEMORY);
    }
    (void)strcpy(commandLine, command);
    (void)strcat(commandLine, " ");
    (void)strcat(commandLine, name);
    (void)strcat(commandLine, " ");
    (void)strcat(commandLine, address);

    /* Convert commandLine from UTF-8 to platform encoding */
    len = (int)strlen(commandLine);
    buf = jvmtiAllocate(len*3+3);
    (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
        (jbyte*)commandLine, len, buf, len*3+3);

    /* Exec commandLine */
    rc = dbgsysExec(buf);

    /* Free up buffers */
    jvmtiDeallocate(buf);
    jvmtiDeallocate(commandLine);

    /* And non-zero exit status means we had an error */
    if (rc != SYS_OK) {
        return JDWP_ERROR(TRANSPORT_INIT);
    }
    return JDWP_ERROR(NONE);
}

jdwpError
transport_startTransport(jboolean isServer, char *name, char *address,
                         long timeout)
{
    jvmtiStartFunction func;
    jdwpTransportEnv *trans;
    char threadName[MAXPATHLEN + 100];
    jint err;
    jdwpError serror;

    /*
     * If the transport is already loaded then use it
     * Note: We're assuming here that we don't support multiple
     * transports - when we do then we need to handle the case
     * where the transport library only supports a single environment.
     * That probably means we have a bag a transport environments
     * to correspond to the transports bag.
     */
    if (transport != NULL) {
        trans = transport;
    } else {
        serror = loadTransport(name, &trans);
        if (serror != JDWP_ERROR(NONE)) {
            return serror;
        }
    }

    if (isServer) {

        char *retAddress;
        char *launchCommand;
        TransportInfo *info;
        jvmtiError error;
        int len;
        char* prop_value;

        info = jvmtiAllocate(sizeof(*info));
        if (info == NULL) {
            return JDWP_ERROR(OUT_OF_MEMORY);
        }
        info->name = jvmtiAllocate((int)strlen(name)+1);
        (void)strcpy(info->name, name);
        info->address = NULL;
        info->timeout = timeout;
        if (info->name == NULL) {
            serror = JDWP_ERROR(OUT_OF_MEMORY);
            goto handleError;
        }
        if (address != NULL) {
            info->address = jvmtiAllocate((int)strlen(address)+1);
            (void)strcpy(info->address, address);
            if (info->address == NULL) {
                serror = JDWP_ERROR(OUT_OF_MEMORY);
                goto handleError;
            }
        }

        info->transport = trans;

        err = (*trans)->StartListening(trans, address, &retAddress);
        if (err != JDWPTRANSPORT_ERROR_NONE) {
            printLastError(trans, err);
            serror = JDWP_ERROR(TRANSPORT_INIT);
            goto handleError;
        }

        /*
         * Record listener address in a system property
         */
        len = (int)strlen(name) + (int)strlen(retAddress) + 2; /* ':' and '\0' */
        prop_value = (char*)jvmtiAllocate(len);
        strcpy(prop_value, name);
        strcat(prop_value, ":");
        strcat(prop_value, retAddress);
        setTransportProperty(getEnv(), prop_value);
        jvmtiDeallocate(prop_value);


        (void)strcpy(threadName, "JDWP Transport Listener: ");
        (void)strcat(threadName, name);

        func = &acceptThread;
        error = spawnNewThread(func, (void*)info, threadName);
        if (error != JVMTI_ERROR_NONE) {
            serror = map2jdwpError(error);
            goto handleError;
        }

        launchCommand = debugInit_launchOnInit();
        if (launchCommand != NULL) {
            serror = launch(launchCommand, name, retAddress);
            if (serror != JDWP_ERROR(NONE)) {
                goto handleError;
            }
        } else {
            if ( ! gdata->quiet ) {
                TTY_MESSAGE(("Listening for transport %s at address: %s",
                    name, retAddress));
            }
        }
        return JDWP_ERROR(NONE);

handleError:
        jvmtiDeallocate(info->name);
        jvmtiDeallocate(info->address);
        jvmtiDeallocate(info);
    } else {
        /*
         * Note that we don't attempt to do a launch here. Launching
         * is currently supported only in server mode.
         */

        /*
         * If we're connecting to another process, there shouldn't be
         * any concurrent listens, so its ok if we block here in this
         * thread, waiting for the attach to finish.
         */
         err = (*trans)->Attach(trans, address, timeout, 0);
         if (err != JDWPTRANSPORT_ERROR_NONE) {
             printLastError(trans, err);
             serror = JDWP_ERROR(TRANSPORT_INIT);
             return serror;
         }

         /*
          * Start the transport loop in a separate thread
          */
         (void)strcpy(threadName, "JDWP Transport Listener: ");
         (void)strcat(threadName, name);

         func = &attachThread;
         err = spawnNewThread(func, (void*)trans, threadName);
         serror = map2jdwpError(err);
    }
    return serror;
}

void
transport_close(void)
{
    if ( transport != NULL ) {
        (*transport)->Close(transport);
    }
}

jboolean
transport_is_open(void)
{
    jboolean is_open = JNI_FALSE;

    if ( transport != NULL ) {
        is_open = (*transport)->IsOpen(transport);
    }
    return is_open;
}

jint
transport_sendPacket(jdwpPacket *packet)
{
    jdwpTransportError err = JDWPTRANSPORT_ERROR_NONE;
    jint rc = 0;

    if (transport != NULL) {
        if ( (*transport)->IsOpen(transport) ) {
            debugMonitorEnter(sendLock);
            err = (*transport)->WritePacket(transport, packet);
            debugMonitorExit(sendLock);
        }
        if (err != JDWPTRANSPORT_ERROR_NONE) {
            if ((*transport)->IsOpen(transport)) {
                printLastError(transport, err);
            }

            /*
             * The users of transport_sendPacket except 0 for
             * success; non-0 otherwise.
             */
            rc = (jint)-1;
        }

    } /* else, bit bucket */

    return rc;
}

jint
transport_receivePacket(jdwpPacket *packet)
{
    jdwpTransportError err;

    err = (*transport)->ReadPacket(transport, packet);
    if (err != JDWPTRANSPORT_ERROR_NONE) {
        /*
         * If transport has been closed return EOF
         */
        if (!(*transport)->IsOpen(transport)) {
            packet->type.cmd.len = 0;
            return 0;
        }

        printLastError(transport, err);

        /*
         * Users of transport_receivePacket expect 0 for success,
         * non-0 otherwise.
         */
        return (jint)-1;
    }
    return 0;
}
