/*
 * Copyright (c) 2003, 2004, 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 <stdlib.h>
#include <stdio.h>
#include <jni.h>
#include "management.h"
#include "sun_management_GcInfoBuilder.h"

JNIEXPORT jint JNICALL Java_sun_management_GcInfoBuilder_getNumGcExtAttributes
  (JNIEnv *env, jobject dummy, jobject gc) {
    jlong value;

    if (gc == NULL) {
        JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
        return 0;
    }
    value = jmm_interface->GetLongAttribute(env, gc,
                                            JMM_GC_EXT_ATTRIBUTE_INFO_SIZE);
    return (jint) value;
}

JNIEXPORT void JNICALL Java_sun_management_GcInfoBuilder_fillGcAttributeInfo
  (JNIEnv *env, jobject dummy, jobject gc,
   jint num_attributes, jobjectArray attributeNames,
   jcharArray types, jobjectArray descriptions) {

    jmmExtAttributeInfo* ext_att_info;
    jchar* nativeTypes;
    jstring attName = NULL;
    jstring desc = NULL;
    jint ret = 0;
    jint i;

    if (gc == NULL) {
        JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
        return;
    }

    if (num_attributes <= 0) {
        JNU_ThrowIllegalArgumentException(env, "Invalid num_attributes");
        return;
    }

    ext_att_info = (jmmExtAttributeInfo*) malloc((size_t)num_attributes *
                                                 sizeof(jmmExtAttributeInfo));
    if (ext_att_info == NULL) {
        JNU_ThrowOutOfMemoryError(env, 0);
        return;
    }
    ret = jmm_interface->GetGCExtAttributeInfo(env, gc,
                                               ext_att_info, num_attributes);
    if (ret != num_attributes) {
        JNU_ThrowInternalError(env, "Unexpected num_attributes");
        free(ext_att_info);
        return;
    }

    nativeTypes = (jchar*) malloc((size_t)num_attributes * sizeof(jchar));
    if (nativeTypes == NULL) {
        free(ext_att_info);
        JNU_ThrowOutOfMemoryError(env, 0);
        return;
    }
    for (i = 0; i < num_attributes; i++) {
        nativeTypes[i] = ext_att_info[i].type;
        attName = (*env)->NewStringUTF(env, ext_att_info[i].name);
        desc = (*env)->NewStringUTF(env, ext_att_info[i].description);
        (*env)->SetObjectArrayElement(env, attributeNames, i, attName);
        (*env)->SetObjectArrayElement(env, descriptions, i, desc);
    }
    (*env)->SetCharArrayRegion(env, types, 0, num_attributes, nativeTypes);

    if (ext_att_info != NULL) {
        free(ext_att_info);
    }
    if (nativeTypes != NULL) {
        free(nativeTypes);
    }
}

static void setLongValueAtObjectArray(JNIEnv *env, jobjectArray array,
                                      jsize index, jlong value) {
    static const char* class_name = "java/lang/Long";
    static const char* signature = "(J)V";
    jobject obj = JNU_NewObjectByName(env, class_name, signature, value);

    (*env)->SetObjectArrayElement(env, array, index, obj);
}

static void setBooleanValueAtObjectArray(JNIEnv *env, jobjectArray array,
                                         jsize index, jboolean value) {
    static const char* class_name = "java/lang/Boolean";
    static const char* signature = "(Z)V";
    jobject obj = JNU_NewObjectByName(env, class_name, signature, value);

    (*env)->SetObjectArrayElement(env, array, index, obj);
}

static void setByteValueAtObjectArray(JNIEnv *env, jobjectArray array,
                                      jsize index, jbyte value) {
    static const char* class_name = "java/lang/Byte";
    static const char* signature = "(B)V";
    jobject obj = JNU_NewObjectByName(env, class_name, signature, value);

    (*env)->SetObjectArrayElement(env, array, index, obj);
}

static void setIntValueAtObjectArray(JNIEnv *env, jobjectArray array,
                                     jsize index, jint value) {
    static const char* class_name = "java/lang/Integer";
    static const char* signature = "(I)V";
    jobject obj = JNU_NewObjectByName(env, class_name, signature, value);

    (*env)->SetObjectArrayElement(env, array, index, obj);
}

static void setShortValueAtObjectArray(JNIEnv *env, jobjectArray array,
                                       jsize index, jshort value) {
    static const char* class_name = "java/lang/Short";
    static const char* signature = "(S)V";
    jobject obj = JNU_NewObjectByName(env, class_name, signature, value);

    (*env)->SetObjectArrayElement(env, array, index, obj);
}

static void setDoubleValueAtObjectArray(JNIEnv *env, jobjectArray array,
                                        jsize index, jdouble value) {
    static const char* class_name = "java/lang/Double";
    static const char* signature = "(D)V";
    jobject obj = JNU_NewObjectByName(env, class_name, signature, value);

    (*env)->SetObjectArrayElement(env, array, index, obj);
}

static void setFloatValueAtObjectArray(JNIEnv *env, jobjectArray array,
                                       jsize index, jfloat value) {
    static const char* class_name = "java/lang/Float";
    static const char* signature = "(D)V";
    jobject obj = JNU_NewObjectByName(env, class_name, signature, value);

    (*env)->SetObjectArrayElement(env, array, index, obj);
}

static void setCharValueAtObjectArray(JNIEnv *env, jobjectArray array,
                                      jsize index, jchar value) {
    static const char* class_name = "java/lang/Character";
    static const char* signature = "(C)V";
    jobject obj = JNU_NewObjectByName(env, class_name, signature, value);

    (*env)->SetObjectArrayElement(env, array, index, obj);
}

JNIEXPORT jobject JNICALL Java_sun_management_GcInfoBuilder_getLastGcInfo0
  (JNIEnv *env, jobject builder, jobject gc,
   jint ext_att_count, jobjectArray ext_att_values, jcharArray ext_att_types,
   jobjectArray usageBeforeGC, jobjectArray usageAfterGC) {

    jmmGCStat   gc_stat;
    jchar*      nativeTypes;
    jsize       i;
    jvalue      v;

    if (gc == NULL) {
        JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
        return 0;
    }

    if (ext_att_count <= 0) {
        JNU_ThrowIllegalArgumentException(env, "Invalid ext_att_count");
        return 0;
    }

    gc_stat.usage_before_gc = usageBeforeGC;
    gc_stat.usage_after_gc = usageAfterGC;
    gc_stat.gc_ext_attribute_values_size = ext_att_count;
    if (ext_att_count > 0) {
        gc_stat.gc_ext_attribute_values = (jvalue*) malloc((size_t)ext_att_count *
                                                           sizeof(jvalue));
        if (gc_stat.gc_ext_attribute_values == NULL) {
            JNU_ThrowOutOfMemoryError(env, 0);
            return 0;
        }
    } else {
        gc_stat.gc_ext_attribute_values = NULL;
    }


    jmm_interface->GetLastGCStat(env, gc, &gc_stat);
    if (gc_stat.gc_index == 0) {
        if (gc_stat.gc_ext_attribute_values != NULL) {
            free(gc_stat.gc_ext_attribute_values);
        }
        return 0;
    }

    // convert the ext_att_types to native types
    nativeTypes = (jchar*) malloc((size_t)ext_att_count * sizeof(jchar));
    if (nativeTypes == NULL) {
        if (gc_stat.gc_ext_attribute_values != NULL) {
            free(gc_stat.gc_ext_attribute_values);
        }
        JNU_ThrowOutOfMemoryError(env, 0);
        return 0;
    }
    (*env)->GetCharArrayRegion(env, ext_att_types, 0, ext_att_count, nativeTypes);
    for (i = 0; i < ext_att_count; i++) {
       v = gc_stat.gc_ext_attribute_values[i];
       switch (nativeTypes[i]) {
            case 'Z':
                setBooleanValueAtObjectArray(env, ext_att_values, i, v.z);
                break;
            case 'B':
                setByteValueAtObjectArray(env, ext_att_values, i, v.b);
                break;
            case 'C':
                setCharValueAtObjectArray(env, ext_att_values, i, v.c);
                break;
            case 'S':
                setShortValueAtObjectArray(env, ext_att_values, i, v.s);
                break;
            case 'I':
                setIntValueAtObjectArray(env, ext_att_values, i, v.i);
                break;
            case 'J':
                setLongValueAtObjectArray(env, ext_att_values, i, v.j);
                break;
            case 'F':
                setFloatValueAtObjectArray(env, ext_att_values, i, v.f);
                break;
            case 'D':
                setDoubleValueAtObjectArray(env, ext_att_values, i, v.d);
                break;
            default:
                if (gc_stat.gc_ext_attribute_values != NULL) {
                    free(gc_stat.gc_ext_attribute_values);
                }
                if (nativeTypes != NULL) {
                    free(nativeTypes);
                }
                JNU_ThrowInternalError(env, "Unsupported attribute type");
                return 0;
       }
    }
    if (gc_stat.gc_ext_attribute_values != NULL) {
        free(gc_stat.gc_ext_attribute_values);
    }
    if (nativeTypes != NULL) {
        free(nativeTypes);
    }

    return JNU_NewObjectByName(env,
       "com/sun/management/GcInfo",
       "(Lsun/management/GcInfoBuilder;JJJ[Ljava/lang/management/MemoryUsage;[Ljava/lang/management/MemoryUsage;[Ljava/lang/Object;)V",
       builder,
       gc_stat.gc_index,
       gc_stat.start_time,
       gc_stat.end_time,
       usageBeforeGC,
       usageAfterGC,
       ext_att_values);
}
