/*
 * Copyright (c) 2003, 2006, 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.
 */

/*
 * 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));
    }

}
