/*
 * Copyright (c) 1998, 2017, 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 "debugDispatch.h"
#include "standardHandlers.h"
#include "inStream.h"
#include "outStream.h"
#include "threadControl.h"


static void JNICALL reader(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg);
static void enqueue(jdwpPacket *p);
static jboolean dequeue(jdwpPacket *p);
static void notifyTransportError(void);

struct PacketList {
    jdwpPacket packet;
    struct PacketList *next;
};

static volatile struct PacketList *cmdQueue;
static jrawMonitorID cmdQueueLock;
static jrawMonitorID vmDeathLock;
static jboolean transportError;

static jboolean
lastCommand(jdwpCmdPacket *cmd)
{
    if ((cmd->cmdSet == JDWP_COMMAND_SET(VirtualMachine)) &&
        ((cmd->cmd == JDWP_COMMAND(VirtualMachine, Dispose)) ||
         (cmd->cmd == JDWP_COMMAND(VirtualMachine, Exit)))) {
        return JNI_TRUE;
    } else {
        return JNI_FALSE;
    }
}

void
debugLoop_initialize(void)
{
    vmDeathLock = debugMonitorCreate("JDWP VM_DEATH Lock");
}

void
debugLoop_sync(void)
{
    debugMonitorEnter(vmDeathLock);
    debugMonitorExit(vmDeathLock);
}

/*
 * This is where all the work gets done.
 */

void
debugLoop_run(void)
{
    jboolean shouldListen;
    jdwpPacket p;
    jvmtiStartFunction func;

    /* Initialize all statics */
    /* We may be starting a new connection after an error */
    cmdQueue = NULL;
    cmdQueueLock = debugMonitorCreate("JDWP Command Queue Lock");
    transportError = JNI_FALSE;

    shouldListen = JNI_TRUE;

    func = &reader;
    (void)spawnNewThread(func, NULL, "JDWP Command Reader");

    standardHandlers_onConnect();
    threadControl_onConnect();

    /* Okay, start reading cmds! */
    while (shouldListen) {
        if (!dequeue(&p)) {
            break;
        }

        if (p.type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) {
            /*
             * Its a reply packet.
             */
           continue;
        } else {
            /*
             * Its a cmd packet.
             */
            jdwpCmdPacket *cmd = &p.type.cmd;
            PacketInputStream in;
            PacketOutputStream out;
            CommandHandler func;

            /* Should reply be sent to sender.
             * For error handling, assume yes, since
             * only VM/exit does not reply
             */
            jboolean replyToSender = JNI_TRUE;

            /*
             * For all commands we hold the vmDeathLock
             * while executing and replying to the command. This ensures
             * that a command after VM_DEATH will be allowed to complete
             * before the thread posting the VM_DEATH continues VM
             * termination.
             */
            debugMonitorEnter(vmDeathLock);

            /* Initialize the input and output streams */
            inStream_init(&in, p);
            outStream_initReply(&out, inStream_id(&in));

            LOG_MISC(("Command set %d, command %d", cmd->cmdSet, cmd->cmd));

            func = debugDispatch_getHandler(cmd->cmdSet,cmd->cmd);
            if (func == NULL) {
                /* we've never heard of this, so I guess we
                 * haven't implemented it.
                 * Handle gracefully for future expansion
                 * and platform / vendor expansion.
                 */
                outStream_setError(&out, JDWP_ERROR(NOT_IMPLEMENTED));
            } else if (gdata->vmDead &&
             ((cmd->cmdSet) != JDWP_COMMAND_SET(VirtualMachine))) {
                /* Protect the VM from calls while dead.
                 * VirtualMachine cmdSet quietly ignores some cmds
                 * after VM death, so, it sends it's own errors.
                 */
                outStream_setError(&out, JDWP_ERROR(VM_DEAD));
            } else {
                /* Call the command handler */
                replyToSender = func(&in, &out);
            }

            /* Reply to the sender */
            if (replyToSender) {
                if (inStream_error(&in)) {
                    outStream_setError(&out, inStream_error(&in));
                }
                outStream_sendReply(&out);
            }

            /*
             * Release the vmDeathLock as the reply has been posted.
             */
            debugMonitorExit(vmDeathLock);

            inStream_destroy(&in);
            outStream_destroy(&out);

            shouldListen = !lastCommand(cmd);
        }
    }
    threadControl_onDisconnect();
    standardHandlers_onDisconnect();

    /*
     * Cut off the transport immediately. This has the effect of
     * cutting off any events that the eventHelper thread might
     * be trying to send.
     */
    transport_close();
    debugMonitorDestroy(cmdQueueLock);

    /* Reset for a new connection to this VM if it's still alive */
    if ( ! gdata->vmDead ) {
        debugInit_reset(getEnv());
    }
}

/* Command reader */
static void JNICALL
reader(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg)
{
    jdwpPacket packet;
    jdwpCmdPacket *cmd;
    jboolean shouldListen = JNI_TRUE;

    LOG_MISC(("Begin reader thread"));

    while (shouldListen) {
        jint rc;

        rc = transport_receivePacket(&packet);

        /* I/O error or EOF */
        if (rc != 0 || (rc == 0 && packet.type.cmd.len == 0)) {
            shouldListen = JNI_FALSE;
            notifyTransportError();
        } else if (packet.type.cmd.flags != JDWPTRANSPORT_FLAGS_NONE) {
            /*
             * Close the connection when we get a jdwpCmdPacket with an
             * invalid flags field value. This is a protocol violation
             * so we drop the connection. Also this could be a web
             * browser generating an HTTP request that passes the JDWP
             * handshake. HTTP requests requires that everything be in
             * the ASCII printable range so a flags value of
             * JDWPTRANSPORT_FLAGS_NONE(0) cannot be generated via HTTP.
             */
            ERROR_MESSAGE(("Received jdwpPacket with flags != 0x%d (actual=0x%x) when a jdwpCmdPacket was expected.",
                           JDWPTRANSPORT_FLAGS_NONE, packet.type.cmd.flags));
            shouldListen = JNI_FALSE;
            notifyTransportError();
        } else {
            cmd = &packet.type.cmd;

            LOG_MISC(("Command set %d, command %d", cmd->cmdSet, cmd->cmd));

            /*
             * FIXME! We need to deal with high priority
             * packets and queue flushes!
             */
            enqueue(&packet);

            shouldListen = !lastCommand(cmd);
        }
    }
    LOG_MISC(("End reader thread"));
}

/*
 * The current system for queueing packets is highly
 * inefficient, and should be rewritten! It'd be nice
 * to avoid any additional memory allocations.
 */

static void
enqueue(jdwpPacket *packet)
{
    struct PacketList *pL;
    struct PacketList *walker;

    pL = jvmtiAllocate((jint)sizeof(struct PacketList));
    if (pL == NULL) {
        EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"packet list");
    }

    pL->packet = *packet;
    pL->next = NULL;

    debugMonitorEnter(cmdQueueLock);

    if (cmdQueue == NULL) {
        cmdQueue = pL;
        debugMonitorNotify(cmdQueueLock);
    } else {
        walker = (struct PacketList *)cmdQueue;
        while (walker->next != NULL)
            walker = walker->next;

        walker->next = pL;
    }

    debugMonitorExit(cmdQueueLock);
}

static jboolean
dequeue(jdwpPacket *packet) {
    struct PacketList *node = NULL;

    debugMonitorEnter(cmdQueueLock);

    while (!transportError && (cmdQueue == NULL)) {
        debugMonitorWait(cmdQueueLock);
    }

    if (cmdQueue != NULL) {
        node = (struct PacketList *)cmdQueue;
        cmdQueue = node->next;
    }
    debugMonitorExit(cmdQueueLock);

    if (node != NULL) {
        *packet = node->packet;
        jvmtiDeallocate(node);
    }
    return (node != NULL);
}

static void
notifyTransportError(void) {
    debugMonitorEnter(cmdQueueLock);
    transportError = JNI_TRUE;
    debugMonitorNotify(cmdQueueLock);
    debugMonitorExit(cmdQueueLock);
}
