/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "tcn.h"

/* Merge IS_ETIMEDOUT with APR_TIMEUP
 */
#define TCN_STATUS_IS_ETIMEDOUT(x) (APR_STATUS_IS_ETIMEDOUT((x)) || ((x) == APR_TIMEUP))
/*
 * Convenience function to help throw an java.lang.Exception.
 */
void tcn_ThrowException(JNIEnv *env, const char *msg)
{
    jclass javaExceptionClass;

    javaExceptionClass = (*env)->FindClass(env, "java/lang/Exception");
    if (javaExceptionClass == NULL) {
        fprintf(stderr, "Cannot find java/lang/Exception class\n");
        return;
    }
    (*env)->ThrowNew(env, javaExceptionClass, msg);
    (*env)->DeleteLocalRef(env, javaExceptionClass);

}

void tcn_ThrowMemoryException(JNIEnv *env, const char *file, int line, const char *msg)
{
    jclass javaExceptionClass;
    javaExceptionClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
    if (javaExceptionClass == NULL) {
        fprintf(stderr, "Cannot find java/lang/OutOfMemoryError\n");
        return;
    }

    if (file) {
        char fmt[TCN_BUFFER_SZ];
        char *f = (char *)(file + strlen(file) - 1);
        while (f != file && '\\' != *f && '/' != *f) {
            f--;
        }
        if (f != file) {
            f++;
        }
        sprintf(fmt, "%s for [%04d@%s]", msg, line, f);
        (*env)->ThrowNew(env, javaExceptionClass, &fmt[0]);
    }
    else
        (*env)->ThrowNew(env, javaExceptionClass, msg);
    (*env)->DeleteLocalRef(env, javaExceptionClass);

}


void tcn_Throw(JNIEnv *env, const char *fmt, ...)
{
    char msg[TCN_BUFFER_SZ] = {'\0'};
    va_list ap;

    va_start(ap, fmt);
    apr_vsnprintf(msg, TCN_BUFFER_SZ, fmt, ap);
    tcn_ThrowException(env, msg);
    va_end(ap);
}

/*
 * Convenience function to help throw an APR Exception
 * from native error code.
 */
void tcn_ThrowAPRException(JNIEnv *e, apr_status_t err)
{
    jclass aprErrorClass;
    jmethodID constructorID = 0;
    jobject throwObj;
    jstring jdescription;
    char serr[512] = {0};

    aprErrorClass = (*e)->FindClass(e, TCN_ERROR_CLASS);
    if (aprErrorClass == NULL) {
        fprintf(stderr, "Cannot find " TCN_ERROR_CLASS " class\n");
        return;
    }

    /* Find the constructor ID */
    constructorID = (*e)->GetMethodID(e, aprErrorClass,
                                      "<init>",
                                      "(ILjava/lang/String;)V");
    if (constructorID == NULL) {
        fprintf(stderr,
                "Cannot find constructor for " TCN_ERROR_CLASS " class\n");
        goto cleanup;
    }

    apr_strerror(err, serr, 512);
    /* Obtain the string objects */
    jdescription = AJP_TO_JSTRING(serr);
    if (jdescription == NULL) {
        fprintf(stderr,
                "Cannot allocate description for " TCN_ERROR_CLASS " class\n");
        goto cleanup;
    }
    /* Create the APR Error object */
    throwObj = (*e)->NewObject(e, aprErrorClass, constructorID,
                               (jint)err, jdescription);
    if (throwObj == NULL) {
        fprintf(stderr,
                "Cannot allocate new " TCN_ERROR_CLASS " object\n");
        goto cleanup;
    }

    (*e)->Throw(e, throwObj);
cleanup:
    (*e)->DeleteLocalRef(e, aprErrorClass);
}
