/*
 * Copyright 2003-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * Copyright 2003 Wily Technology, Inc.
 */

#include    <jni.h>
#include    <jvmti.h>

#include    "JPLISAssert.h"
#include    "Utilities.h"
#include    "JavaExceptions.h"

/**
 * This module contains utility routines for manipulating Java throwables
 * and JNIEnv throwable state from native code.
 */

static jthrowable   sFallbackInternalError  = NULL;

/*
 * Local forward declarations.
 */

/* insist on having a throwable. If we already have one, return it.
 * If not, map to fallback
 */
jthrowable
forceFallback(jthrowable potentialException);


jthrowable
forceFallback(jthrowable potentialException) {
    if ( potentialException == NULL ) {
        return sFallbackInternalError;
    }
    else {
        return potentialException;
    }
}

/**
 *  Returns true if it properly sets up a fallback exception
 */
jboolean
initializeFallbackError(JNIEnv* jnienv) {
    jplis_assert(isSafeForJNICalls(jnienv));
    sFallbackInternalError = createInternalError(jnienv, NULL);
    jplis_assert(isSafeForJNICalls(jnienv));
    return (sFallbackInternalError != NULL);
}


/*
 *  Map everything to InternalError.
 */
jthrowable
mapAllCheckedToInternalErrorMapper( JNIEnv *    jnienv,
                                    jthrowable  throwableToMap) {
    jthrowable  mappedThrowable = NULL;
    jstring     message         = NULL;

    jplis_assert(throwableToMap != NULL);
    jplis_assert(isSafeForJNICalls(jnienv));
    jplis_assert(!isUnchecked(jnienv, throwableToMap));

    message = getMessageFromThrowable(jnienv, throwableToMap);
    mappedThrowable = createInternalError(jnienv, message);

    jplis_assert(isSafeForJNICalls(jnienv));
    return mappedThrowable;
}


jboolean
checkForThrowable(  JNIEnv*     jnienv) {
    return (*jnienv)->ExceptionCheck(jnienv);
}

jboolean
isSafeForJNICalls(  JNIEnv * jnienv) {
    return !(*jnienv)->ExceptionCheck(jnienv);
}


void
logThrowable(   JNIEnv * jnienv) {
    if ( checkForThrowable(jnienv) ) {
        (*jnienv)->ExceptionDescribe(jnienv);
    }
}



/**
 *  Creates an exception or error with the fully qualified classname (ie java/lang/Error)
 *  and message passed to its constructor
 */
jthrowable
createThrowable(    JNIEnv *        jnienv,
                    const char *    className,
                    jstring         message) {
    jthrowable  exception           = NULL;
    jmethodID   constructor         = NULL;
    jclass      exceptionClass      = NULL;
    jboolean    errorOutstanding    = JNI_FALSE;

    jplis_assert(className != NULL);
    jplis_assert(isSafeForJNICalls(jnienv));

    /* create new VMError with message from exception */
    exceptionClass = (*jnienv)->FindClass(jnienv, className);
    errorOutstanding = checkForAndClearThrowable(jnienv);
    jplis_assert(!errorOutstanding);

    if (!errorOutstanding) {
        constructor = (*jnienv)->GetMethodID(   jnienv,
                                                exceptionClass,
                                                "<init>",
                                                "(Ljava/lang/String;)V");
        errorOutstanding = checkForAndClearThrowable(jnienv);
        jplis_assert(!errorOutstanding);
    }

    if (!errorOutstanding) {
        exception = (*jnienv)->NewObject(jnienv, exceptionClass, constructor, message);
        errorOutstanding = checkForAndClearThrowable(jnienv);
        jplis_assert(!errorOutstanding);
    }

    jplis_assert(isSafeForJNICalls(jnienv));
    return exception;
}

jthrowable
createInternalError(JNIEnv * jnienv, jstring message) {
    return createThrowable( jnienv,
                            "java/lang/InternalError",
                            message);
}

jthrowable
createThrowableFromJVMTIErrorCode(JNIEnv * jnienv, jvmtiError errorCode) {
    const char * throwableClassName = NULL;
    const char * message            = NULL;
    jstring messageString           = NULL;

    switch ( errorCode ) {
        case JVMTI_ERROR_NULL_POINTER:
                throwableClassName = "java/lang/NullPointerException";
                break;

        case JVMTI_ERROR_ILLEGAL_ARGUMENT:
                throwableClassName = "java/lang/IllegalArgumentException";
                break;

        case JVMTI_ERROR_OUT_OF_MEMORY:
                throwableClassName = "java/lang/OutOfMemoryError";
                break;

        case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
                throwableClassName = "java/lang/ClassCircularityError";
                break;

        case JVMTI_ERROR_FAILS_VERIFICATION:
                throwableClassName = "java/lang/VerifyError";
                break;

        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
                throwableClassName = "java/lang/UnsupportedOperationException";
                message = "class redefinition failed: attempted to add a method";
                break;

        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
                throwableClassName = "java/lang/UnsupportedOperationException";
                message = "class redefinition failed: attempted to change the schema (add/remove fields)";
                break;

        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
                throwableClassName = "java/lang/UnsupportedOperationException";
                message = "class redefinition failed: attempted to change superclass or interfaces";
                break;

        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
                throwableClassName = "java/lang/UnsupportedOperationException";
                message = "class redefinition failed: attempted to delete a method";
                break;

        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
                throwableClassName = "java/lang/UnsupportedOperationException";
                message = "class redefinition failed: attempted to change the class modifiers";
                break;

        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
                throwableClassName = "java/lang/UnsupportedOperationException";
                message = "class redefinition failed: attempted to change method modifiers";
                break;

        case JVMTI_ERROR_UNSUPPORTED_VERSION:
                throwableClassName = "java/lang/UnsupportedClassVersionError";
                break;

        case JVMTI_ERROR_NAMES_DONT_MATCH:
                throwableClassName = "java/lang/NoClassDefFoundError";
                message = "class names don't match";
                break;

        case JVMTI_ERROR_INVALID_CLASS_FORMAT:
                throwableClassName = "java/lang/ClassFormatError";
                break;

        case JVMTI_ERROR_UNMODIFIABLE_CLASS:
                throwableClassName = "java/lang/instrument/UnmodifiableClassException";
                break;

        case JVMTI_ERROR_INVALID_CLASS:
                throwableClassName = "java/lang/InternalError";
                message = "class redefinition failed: invalid class";
                break;

        case JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED:
                throwableClassName = "java/lang/UnsupportedOperationException";
                message = "unsupported operation";
                break;

        case JVMTI_ERROR_INTERNAL:
        default:
                throwableClassName = "java/lang/InternalError";
                break;
        }

    if ( message != NULL ) {
        jboolean errorOutstanding;

        messageString = (*jnienv)->NewStringUTF(jnienv, message);
        errorOutstanding = checkForAndClearThrowable(jnienv);
        jplis_assert_msg(!errorOutstanding, "can't create exception java string");
    }
    return createThrowable( jnienv,
                            throwableClassName,
                            messageString);

}


/**
 *  Calls toString() on the given message which is the same call made by
 *  Exception when passed a throwable to its constructor
 */
jstring
getMessageFromThrowable(    JNIEnv*     jnienv,
                            jthrowable  exception) {
    jclass      exceptionClass      = NULL;
    jmethodID   method              = NULL;
    jstring     message             = NULL;
    jboolean    errorOutstanding    = JNI_FALSE;

    jplis_assert(isSafeForJNICalls(jnienv));

    /* call getMessage on exception */
    exceptionClass = (*jnienv)->GetObjectClass(jnienv, exception);
    errorOutstanding = checkForAndClearThrowable(jnienv);
    jplis_assert(!errorOutstanding);

    if (!errorOutstanding) {
        method = (*jnienv)->GetMethodID(jnienv,
                                        exceptionClass,
                                        "toString",
                                        "()Ljava/lang/String;");
        errorOutstanding = checkForAndClearThrowable(jnienv);
        jplis_assert(!errorOutstanding);
    }

    if (!errorOutstanding) {
        message = (*jnienv)->CallObjectMethod(jnienv, exception, method);
        errorOutstanding = checkForAndClearThrowable(jnienv);
        jplis_assert(!errorOutstanding);
    }

    jplis_assert(isSafeForJNICalls(jnienv));

    return message;
}


/**
 *  Returns whether the exception given is an unchecked exception:
 *  a subclass of Error or RuntimeException
 */
jboolean
isUnchecked(    JNIEnv*     jnienv,
                jthrowable  exception) {
    jboolean result = JNI_FALSE;

    jplis_assert(isSafeForJNICalls(jnienv));
    result =    (exception == NULL) ||
                isInstanceofClassName(jnienv, exception, "java/lang/Error") ||
                isInstanceofClassName(jnienv, exception, "java/lang/RuntimeException");
    jplis_assert(isSafeForJNICalls(jnienv));
    return result;
}

/*
 *  Returns the current throwable, if any. Clears the throwable state.
 *  Clients can use this to preserve the current throwable state on the stack.
 */
jthrowable
preserveThrowable(JNIEnv * jnienv) {
    jthrowable result = (*jnienv)->ExceptionOccurred(jnienv);
    if ( result != NULL ) {
        (*jnienv)->ExceptionClear(jnienv);
    }
    return result;
}

/*
 *  Installs the supplied throwable into the JNIEnv if the throwable is not null.
 *  Clients can use this to preserve the current throwable state on the stack.
 */
void
restoreThrowable(   JNIEnv *    jnienv,
                    jthrowable  preservedException) {
    throwThrowable( jnienv,
                    preservedException);
    return;
}

void
throwThrowable(     JNIEnv *    jnienv,
                    jthrowable  exception) {
    if ( exception != NULL ) {
        jint result = (*jnienv)->Throw(jnienv, exception);
        jplis_assert_msg(result == JNI_OK, "throwThrowable failed to re-throw");
    }
    return;
}


/*
 *  Always clears the JNIEnv throwable state. Returns true if an exception was present
 *  before the clearing operation.
 */
jboolean
checkForAndClearThrowable(  JNIEnv *    jnienv) {
    jboolean result = (*jnienv)->ExceptionCheck(jnienv);
    if ( result ) {
        (*jnienv)->ExceptionClear(jnienv);
    }
    return result;
}

/* creates a java.lang.InternalError and installs it into the JNIEnv */
void
createAndThrowInternalError(JNIEnv * jnienv) {
    jthrowable internalError = createInternalError( jnienv, NULL);
    throwThrowable(jnienv, forceFallback(internalError));
}

void
createAndThrowThrowableFromJVMTIErrorCode(JNIEnv * jnienv, jvmtiError errorCode) {
    jthrowable throwable = createThrowableFromJVMTIErrorCode(jnienv, errorCode);
    throwThrowable(jnienv, forceFallback(throwable));
}

void
mapThrownThrowableIfNecessary(  JNIEnv *                jnienv,
                                CheckedExceptionMapper  mapper) {
    jthrowable  originalThrowable   = NULL;
    jthrowable  resultThrowable     = NULL;

    originalThrowable = preserveThrowable(jnienv);

    /* the throwable is now cleared, so JNI calls are safe */
    if ( originalThrowable != NULL ) {
        /* if there is an exception: we can just throw it if it is unchecked. If checked,
         * we need to map it (mapper is conditional, will vary by usage, hence the callback)
         */
        if ( isUnchecked(jnienv, originalThrowable) ) {
            resultThrowable = originalThrowable;
        }
        else {
            resultThrowable = (*mapper) (jnienv, originalThrowable);
        }
    }

    /* re-establish the correct throwable */
    if ( resultThrowable != NULL ) {
        throwThrowable(jnienv, forceFallback(resultThrowable));
    }

}
