/*
 * Copyright (c) 1998, 2008, 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 "ThreadReferenceImpl.h"
#include "eventHandler.h"
#include "threadControl.h"
#include "inStream.h"
#include "outStream.h"
#include "FrameID.h"

static jboolean
name(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    jthread thread;

    env = getEnv();

    thread = inStream_readThreadRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    WITH_LOCAL_REFS(env, 1) {

        jvmtiThreadInfo info;
        jvmtiError error;

        (void)memset(&info, 0, sizeof(info));

        error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
                                (gdata->jvmti, thread, &info);

        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            (void)outStream_writeString(out, info.name);
        }

        if ( info.name != NULL )
            jvmtiDeallocate(info.name);

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
suspend(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;
    jthread thread;

    thread = inStream_readThreadRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }
    error = threadControl_suspendThread(thread, JNI_FALSE);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    }
    return JNI_TRUE;
}

static jboolean
resume(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;
    jthread thread;

    thread = inStream_readThreadRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    /* true means it is okay to unblock the commandLoop thread */
    error = threadControl_resumeThread(thread, JNI_TRUE);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    }
    return JNI_TRUE;
}

static jboolean
status(PacketInputStream *in, PacketOutputStream *out)
{
    jdwpThreadStatus threadStatus;
    jint statusFlags;
    jvmtiError error;
    jthread thread;

    thread = inStream_readThreadRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    error = threadControl_applicationThreadStatus(thread, &threadStatus,
                                                          &statusFlags);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }
    (void)outStream_writeInt(out, threadStatus);
    (void)outStream_writeInt(out, statusFlags);
    return JNI_TRUE;
}

static jboolean
threadGroup(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    jthread thread;

    env = getEnv();

    thread = inStream_readThreadRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    WITH_LOCAL_REFS(env, 1) {

        jvmtiThreadInfo info;
        jvmtiError error;

        (void)memset(&info, 0, sizeof(info));

        error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
                                (gdata->jvmti, thread, &info);

        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            (void)outStream_writeObjectRef(env, out, info.thread_group);
        }

        if ( info.name!=NULL )
            jvmtiDeallocate(info.name);

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
validateSuspendedThread(PacketOutputStream *out, jthread thread)
{
    jvmtiError error;
    jint count;

    error = threadControl_suspendCount(thread, &count);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_FALSE;
    }

    if (count == 0) {
        outStream_setError(out, JDWP_ERROR(THREAD_NOT_SUSPENDED));
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

static jboolean
frames(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;
    FrameNumber fnum;
    jint count;
    JNIEnv *env;
    jthread thread;
    jint startIndex;
    jint length;

    env = getEnv();

    thread = inStream_readThreadRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    startIndex = inStream_readInt(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    length = inStream_readInt(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    if (!validateSuspendedThread(out, thread)) {
        return JNI_TRUE;
    }

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)
                        (gdata->jvmti, thread, &count);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    if (length == -1) {
        length = count - startIndex;
    }

    if (length == 0) {
        (void)outStream_writeInt(out, 0);
        return JNI_TRUE;
    }

    if ((startIndex < 0) || (startIndex > count - 1)) {
        outStream_setError(out, JDWP_ERROR(INVALID_INDEX));
        return JNI_TRUE;
    }

    if ((length < 0) || (length + startIndex > count)) {
        outStream_setError(out, JDWP_ERROR(INVALID_LENGTH));
        return JNI_TRUE;
    }

    (void)outStream_writeInt(out, length);

    for(fnum = startIndex ; fnum < startIndex+length ; fnum++ ) {

        WITH_LOCAL_REFS(env, 1) {

            jclass clazz;
            jmethodID method;
            jlocation location;

            /* Get location info */
            error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)
                (gdata->jvmti, thread, fnum, &method, &location);
            if (error == JVMTI_ERROR_OPAQUE_FRAME) {
                clazz = NULL;
                location = -1L;
                error = JVMTI_ERROR_NONE;
            } else if ( error == JVMTI_ERROR_NONE ) {
                error = methodClass(method, &clazz);
                if ( error == JVMTI_ERROR_NONE ) {
                    FrameID frame;
                    frame = createFrameID(thread, fnum);
                    (void)outStream_writeFrameID(out, frame);
                    writeCodeLocation(out, clazz, method, location);
                }
            }

        } END_WITH_LOCAL_REFS(env);

        if (error != JVMTI_ERROR_NONE)
            break;

    }

    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    }
    return JNI_TRUE;
}

static jboolean
getFrameCount(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;
    jint count;
    jthread thread;

    thread = inStream_readThreadRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    if (!validateSuspendedThread(out, thread)) {
        return JNI_TRUE;
    }

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)
                        (gdata->jvmti, thread, &count);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }
    (void)outStream_writeInt(out, count);

    return JNI_TRUE;
}

static jboolean
ownedMonitors(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    jthread thread;

    env = getEnv();

    thread = inStream_readThreadRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    if (!validateSuspendedThread(out, thread)) {
        return JNI_TRUE;
    }

    WITH_LOCAL_REFS(env, 1) {

        jvmtiError error;
        jint count = 0;
        jobject *monitors = NULL;

        error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorInfo)
                                (gdata->jvmti, thread, &count, &monitors);
        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            int i;
            (void)outStream_writeInt(out, count);
            for (i = 0; i < count; i++) {
                jobject monitor = monitors[i];
                (void)outStream_writeByte(out, specificTypeKey(env, monitor));
                (void)outStream_writeObjectRef(env, out, monitor);
            }
        }
        if (monitors != NULL)
            jvmtiDeallocate(monitors);

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
currentContendedMonitor(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    jthread thread;

    env = getEnv();

    thread = inStream_readThreadRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (thread == NULL || threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    if (!validateSuspendedThread(out, thread)) {
        return JNI_TRUE;
    }

    WITH_LOCAL_REFS(env, 1) {

        jobject monitor;
        jvmtiError error;

        error = JVMTI_FUNC_PTR(gdata->jvmti,GetCurrentContendedMonitor)
                                (gdata->jvmti, thread, &monitor);

        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            (void)outStream_writeByte(out, specificTypeKey(env, monitor));
            (void)outStream_writeObjectRef(env, out, monitor);
        }

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
stop(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;
    jthread thread;
    jobject throwable;
    JNIEnv *env;

    env = getEnv();
    thread = inStream_readThreadRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    throwable = inStream_readObjectRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    error = threadControl_stop(thread, throwable);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    }
    return JNI_TRUE;
}

static jboolean
interrupt(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;
    jthread thread;

    thread = inStream_readThreadRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    error = threadControl_interrupt(thread);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    }
    return JNI_TRUE;
}

static jboolean
suspendCount(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;
    jint count;
    jthread thread;

    thread = inStream_readThreadRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    error = threadControl_suspendCount(thread, &count);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeInt(out, count);
    return JNI_TRUE;
}

static jboolean
ownedMonitorsWithStackDepth(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    jthread thread;

    thread = inStream_readThreadRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (thread == NULL || threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    if (!validateSuspendedThread(out, thread)) {
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        jvmtiError error = JVMTI_ERROR_NONE;
        jint count = 0;
        jvmtiMonitorStackDepthInfo *monitors=NULL;

        error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorStackDepthInfo)
                                (gdata->jvmti, thread, &count, &monitors);

        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            int i;
            (void)outStream_writeInt(out, count);
            for (i = 0; i < count; i++) {
                jobject monitor = monitors[i].monitor;
                (void)outStream_writeByte(out, specificTypeKey(env, monitor));
                (void)outStream_writeObjectRef(getEnv(), out, monitor);
                (void)outStream_writeInt(out,monitors[i].stack_depth);
            }
        }
        if (monitors != NULL) {
            jvmtiDeallocate(monitors);
        }

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
forceEarlyReturn(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    jthread thread;
    jvalue value;
    jbyte typeKey;
    jvmtiError error;

    env = getEnv();
    thread = inStream_readThreadRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (threadControl_isDebugThread(thread)) {
        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
        return JNI_TRUE;
    }

    typeKey = inStream_readByte(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    if (isObjectTag(typeKey)) {
        value.l = inStream_readObjectRef(env, in);
        error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnObject)
                        (gdata->jvmti, thread, value.l);
    } else {
        switch (typeKey) {
            case JDWP_TAG(VOID):
                error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnVoid)
                                (gdata->jvmti, thread);
                break;
            case JDWP_TAG(BYTE):
                value.b = inStream_readByte(in);
                error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
                                (gdata->jvmti, thread, value.b);
                break;

            case JDWP_TAG(CHAR):
                value.c = inStream_readChar(in);
                error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
                                (gdata->jvmti, thread, value.c);
                break;

            case JDWP_TAG(FLOAT):
                value.f = inStream_readFloat(in);
                error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnFloat)
                                (gdata->jvmti, thread, value.f);
                break;

            case JDWP_TAG(DOUBLE):
                value.d = inStream_readDouble(in);
                error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnDouble)
                                (gdata->jvmti, thread, value.d);
                break;

            case JDWP_TAG(INT):
                value.i = inStream_readInt(in);
                error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
                                (gdata->jvmti, thread, value.i);
                break;

            case JDWP_TAG(LONG):
                value.j = inStream_readLong(in);
                error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnLong)
                                (gdata->jvmti, thread, value.j);
                break;

            case JDWP_TAG(SHORT):
                value.s = inStream_readShort(in);
                error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
                                (gdata->jvmti, thread, value.s);
                break;

            case JDWP_TAG(BOOLEAN):
                value.z = inStream_readBoolean(in);
                error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
                                (gdata->jvmti, thread, value.z);
                break;

            default:
                error =  AGENT_ERROR_INVALID_TAG;
                break;
        }
    }
    {
      jdwpError serror = map2jdwpError(error);
      if (serror != JDWP_ERROR(NONE)) {
        outStream_setError(out, serror);
      }
    }
    return JNI_TRUE;
}


void *ThreadReference_Cmds[] = { (void *)14,
    (void *)name,
    (void *)suspend,
    (void *)resume,
    (void *)status,
    (void *)threadGroup,
    (void *)frames,
    (void *)getFrameCount,
    (void *)ownedMonitors,
    (void *)currentContendedMonitor,
    (void *)stop,
    (void *)interrupt,
    (void *)suspendCount,
    (void *)ownedMonitorsWithStackDepth,
    (void *)forceEarlyReturn
    };
