/*
 * Copyright (c) 1998, 2005, 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 "ReferenceTypeImpl.h"
#include "inStream.h"
#include "outStream.h"


static jboolean
signature(PacketInputStream *in, PacketOutputStream *out)
{
    char *signature = NULL;
    jclass clazz;
    jvmtiError error;

    clazz = inStream_readClassRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    error = classSignature(clazz, &signature, NULL);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeString(out, signature);
    jvmtiDeallocate(signature);

    return JNI_TRUE;
}

static jboolean
signatureWithGeneric(PacketInputStream *in, PacketOutputStream *out)
{
  /* Returns both the signature and the generic signature */
    char *signature = NULL;
    char *genericSignature = NULL;
    jclass clazz;
    jvmtiError error;

    clazz = inStream_readClassRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    error = classSignature(clazz, &signature, &genericSignature);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeString(out, signature);
    writeGenericSignature(out, genericSignature);
    jvmtiDeallocate(signature);
    if (genericSignature != NULL) {
      jvmtiDeallocate(genericSignature);
    }


    return JNI_TRUE;
}

static jboolean
getClassLoader(PacketInputStream *in, PacketOutputStream *out)
{
    jclass clazz;
    jobject loader;
    jvmtiError error;
    JNIEnv *env;

    env = getEnv();

    clazz = inStream_readClassRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

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

    (void)outStream_writeObjectRef(env, out, loader);
    return JNI_TRUE;
}

static jboolean
modifiers(PacketInputStream *in, PacketOutputStream *out)
{
    jint modifiers;
    jclass clazz;
    jvmtiError error;

    clazz = inStream_readClassRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassModifiers)
                (gdata->jvmti, clazz, &modifiers);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeInt(out, modifiers);

    return JNI_TRUE;
}

static void
writeMethodInfo(PacketOutputStream *out, jclass clazz, jmethodID method,
                int outputGenerics)
{
    char *name = NULL;
    char *signature = NULL;
    char *genericSignature = NULL;
    jint modifiers;
    jvmtiError error;
    jboolean isSynthetic;

    error = isMethodSynthetic(method, &isSynthetic);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return;
    }

    error = methodModifiers(method, &modifiers);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return;
    }

    error = methodSignature(method, &name, &signature, &genericSignature);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return;
    }

    if (isSynthetic) {
        modifiers |= MOD_SYNTHETIC;
    }
    (void)outStream_writeMethodID(out, method);
    (void)outStream_writeString(out, name);
    (void)outStream_writeString(out, signature);
    if (outputGenerics == 1) {
        writeGenericSignature(out, genericSignature);
    }
    (void)outStream_writeInt(out, modifiers);
    jvmtiDeallocate(name);
    jvmtiDeallocate(signature);
    if (genericSignature != NULL) {
      jvmtiDeallocate(genericSignature);
    }
}

static jboolean
methods1(PacketInputStream *in, PacketOutputStream *out,
         int outputGenerics)
{
    int i;
    jclass clazz;
    jint methodCount = 0;
    jmethodID *methods = NULL;
    jvmtiError error;

    clazz = inStream_readClassRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassMethods)
                (gdata->jvmti, clazz, &methodCount, &methods);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeInt(out, methodCount);
    for (i = 0; (i < methodCount) && !outStream_error(out); i++) {
        writeMethodInfo(out, clazz, methods[i], outputGenerics);
    }

    /* Free methods array */
    if ( methods != NULL ) {
        jvmtiDeallocate(methods);
    }
    return JNI_TRUE;
}

static jboolean
methods(PacketInputStream *in, PacketOutputStream *out,
         int outputGenerics)
{
    return methods1(in, out, 0);
}

static jboolean
methodsWithGeneric(PacketInputStream *in, PacketOutputStream *out)
{
    return methods1(in, out, 1);
}



static jboolean
instances(PacketInputStream *in, PacketOutputStream *out)
{
    jint maxInstances;
    jclass clazz;
    JNIEnv *env;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    env = getEnv();
    clazz = inStream_readClassRef(env, in);
    maxInstances = inStream_readInt(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    WITH_LOCAL_REFS(env, 1) {
        jvmtiError   error;
        ObjectBatch  batch;

        error = classInstances(clazz, &batch, maxInstances);
        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            int kk;
            jbyte typeKey;

            (void)outStream_writeInt(out, batch.count);
            if (batch.count > 0) {
                /*
                 * They are all instances of this class and will all have
                 * the same typeKey, so just compute it once.
                 */
                typeKey = specificTypeKey(env, batch.objects[0]);

                for (kk = 0; kk < batch.count; kk++) {
                  jobject inst;

                  inst = batch.objects[kk];
                  (void)outStream_writeByte(out, typeKey);
                  (void)outStream_writeObjectRef(env, out, inst);
                }
            }
            jvmtiDeallocate(batch.objects);
        }
    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
getClassVersion(PacketInputStream *in, PacketOutputStream *out)
{
    jclass clazz;
    jvmtiError error;
    jint majorVersion;
    jint minorVersion;

    clazz = inStream_readClassRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    error = JVMTI_FUNC_PTR(gdata->jvmti, GetClassVersionNumbers)
                (gdata->jvmti, clazz, &minorVersion, &majorVersion);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeInt(out, majorVersion);
    (void)outStream_writeInt(out, minorVersion);

    return JNI_TRUE;
}

static jboolean
getConstantPool(PacketInputStream *in, PacketOutputStream *out)
{

    jclass clazz;
    jvmtiError error;
    jint cpCount;
    jint cpByteCount;
    unsigned char* cpBytesPtr;


    clazz = inStream_readClassRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    /* Initialize assuming no bytecodes and no error */
    error         = JVMTI_ERROR_NONE;
    cpCount       = 0;
    cpByteCount   = 0;
    cpBytesPtr    = NULL;


    error = JVMTI_FUNC_PTR(gdata->jvmti,GetConstantPool)
                (gdata->jvmti, clazz, &cpCount, &cpByteCount, &cpBytesPtr);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    } else {
        (void)outStream_writeInt(out, cpCount);
        (void)outStream_writeByteArray(out, cpByteCount, (jbyte *)cpBytesPtr);
        jvmtiDeallocate(cpBytesPtr);
    }

    return JNI_TRUE;
}

static void
writeFieldInfo(PacketOutputStream *out, jclass clazz, jfieldID fieldID,
               int outputGenerics)
{
    char *name;
    char *signature = NULL;
    char *genericSignature = NULL;
    jint modifiers;
    jboolean isSynthetic;
    jvmtiError error;

    error = isFieldSynthetic(clazz, fieldID, &isSynthetic);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return;
    }

    error = fieldModifiers(clazz, fieldID, &modifiers);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return;
    }

    error = fieldSignature(clazz, fieldID, &name, &signature, &genericSignature);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return;
    }
    if (isSynthetic) {
        modifiers |= MOD_SYNTHETIC;
    }
    (void)outStream_writeFieldID(out, fieldID);
    (void)outStream_writeString(out, name);
    (void)outStream_writeString(out, signature);
    if (outputGenerics == 1) {
        writeGenericSignature(out, genericSignature);
    }
    (void)outStream_writeInt(out, modifiers);
    jvmtiDeallocate(name);
    jvmtiDeallocate(signature);
    if (genericSignature != NULL) {
      jvmtiDeallocate(genericSignature);
    }
}

static jboolean
fields1(PacketInputStream *in, PacketOutputStream *out, int outputGenerics)
{
    int i;
    jclass clazz;
    jint fieldCount = 0;
    jfieldID *fields = NULL;
    jvmtiError error;

    clazz = inStream_readClassRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassFields)
                (gdata->jvmti, clazz, &fieldCount, &fields);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeInt(out, fieldCount);
    for (i = 0; (i < fieldCount) && !outStream_error(out); i++) {
        writeFieldInfo(out, clazz, fields[i], outputGenerics);
    }

    /* Free fields array */
    if ( fields != NULL ) {
        jvmtiDeallocate(fields);
    }
    return JNI_TRUE;
}


static jboolean
fields(PacketInputStream *in, PacketOutputStream *out)
{
    return fields1(in, out, 0);
}

static jboolean
fieldsWithGeneric(PacketInputStream *in, PacketOutputStream *out)
{
    return fields1(in, out, 1);

}

static jboolean
getValues(PacketInputStream *in, PacketOutputStream *out)
{
    sharedGetFieldValues(in, out, JNI_TRUE);
    return JNI_TRUE;
}

static jboolean
sourceFile(PacketInputStream *in, PacketOutputStream *out)
{
    char *fileName;
    jvmtiError error;
    jclass clazz;

    clazz = inStream_readClassRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetSourceFileName)
                (gdata->jvmti, clazz, &fileName);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeString(out, fileName);
    jvmtiDeallocate(fileName);
    return JNI_TRUE;
}

static jboolean
sourceDebugExtension(PacketInputStream *in, PacketOutputStream *out)
{
    char *extension;
    jvmtiError error;
    jclass clazz;

    clazz = inStream_readClassRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

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

    (void)outStream_writeString(out, extension);
    jvmtiDeallocate(extension);
    return JNI_TRUE;
}

static jboolean
nestedTypes(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    jclass clazz;

    env = getEnv();

    clazz = inStream_readClassRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    WITH_LOCAL_REFS(env, 1) {

        jvmtiError error;
        jint count;
        jclass *nested;

        error = allNestedClasses(clazz, &nested, &count);
        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            int i;
            (void)outStream_writeInt(out, count);
            for (i = 0; i < count; i++) {
                (void)outStream_writeByte(out, referenceTypeTag(nested[i]));
                (void)outStream_writeObjectRef(env, out, nested[i]);
            }
            if ( nested != NULL ) {
                jvmtiDeallocate(nested);
            }
        }

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
getClassStatus(PacketInputStream *in, PacketOutputStream *out)
{
    jint status;
    jclass clazz;

    clazz = inStream_readClassRef(getEnv(), in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    status = classStatus(clazz);
    (void)outStream_writeInt(out, map2jdwpClassStatus(status));
    return JNI_TRUE;
}

static jboolean
interfaces(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    jclass clazz;

    env = getEnv();

    clazz = inStream_readClassRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    WITH_LOCAL_REFS(env, 1) {

        jvmtiError error;
        jint interfaceCount;
        jclass *interfaces;

        error = allInterfaces(clazz, &interfaces, &interfaceCount);
        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            int i;

            (void)outStream_writeInt(out, interfaceCount);
            for (i = 0; i < interfaceCount; i++) {
                (void)outStream_writeObjectRef(env, out, interfaces[i]);
            }
            if ( interfaces != NULL ) {
                jvmtiDeallocate(interfaces);
            }
        }

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
classObject(PacketInputStream *in, PacketOutputStream *out)
{
    jclass clazz;
    JNIEnv *env;

    env = getEnv();
    clazz = inStream_readClassRef(env, in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    /*
     * In our implementation, the reference type id is the same as the
     * class object id, so we bounce it right back.
     *
     */

    (void)outStream_writeObjectRef(env, out, clazz);

    return JNI_TRUE;
}

void *ReferenceType_Cmds[] = { (void *)18
    ,(void *)signature
    ,(void *)getClassLoader
    ,(void *)modifiers
    ,(void *)fields
    ,(void *)methods
    ,(void *)getValues
    ,(void *)sourceFile
    ,(void *)nestedTypes
    ,(void *)getClassStatus
    ,(void *)interfaces
    ,(void *)classObject
    ,(void *)sourceDebugExtension
    ,(void *)signatureWithGeneric
    ,(void *)fieldsWithGeneric
    ,(void *)methodsWithGeneric
    ,(void *)instances
    ,(void *)getClassVersion
    ,(void *)getConstantPool
};
