/*
 * 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.
 */

// ReSharper disable once CppUnusedIncludeDirective
#include <cstring>   // needed only on linux
#include <string>
#include <exception>
#include <vector>
#include <algorithm>
#include <stdexcept>

#include "ignite/jni/utils.h"
#include "ignite/common/concurrent.h"
#include "ignite/jni/java.h"
#include <ignite/ignite_error.h>

#define IGNITE_SAFE_PROC_NO_ARG(jniEnv, envPtr, type, field) { \
    JniHandlers* hnds = reinterpret_cast<JniHandlers*>(envPtr); \
    type hnd = hnds->field; \
    if (hnd) \
    { \
        try \
        { \
            hnd(hnds->target); \
        } \
        catch (std::exception& err) \
        { \
            ThrowToJava(jniEnv, err.what()); \
        } \
    } \
    else \
        ThrowOnMissingHandler(jniEnv); \
}

#define IGNITE_SAFE_PROC(jniEnv, envPtr, type, field, ...) { \
    JniHandlers* hnds = reinterpret_cast<JniHandlers*>(envPtr); \
    type hnd = hnds->field; \
    if (hnd) \
    { \
        try \
        { \
            hnd(hnds->target, __VA_ARGS__); \
        } \
        catch (std::exception& err) \
        { \
            ThrowToJava(jniEnv, err.what()); \
        } \
    } \
    else \
        ThrowOnMissingHandler(jniEnv); \
}

#define IGNITE_SAFE_FUNC(jniEnv, envPtr, type, field, ...) { \
    JniHandlers* hnds = reinterpret_cast<JniHandlers*>(envPtr); \
    type hnd = hnds->field; \
    if (hnd) \
    { \
        try \
        { \
            return hnd(hnds->target, __VA_ARGS__); \
        } \
        catch (std::exception& err) \
        { \
            ThrowToJava(jniEnv, err.what()); \
            return 0; \
        } \
    } \
    else \
    { \
        ThrowOnMissingHandler(jniEnv); \
        return 0; \
    }\
}

using namespace ignite::java;

namespace ignite
{
    namespace jni
    {
        namespace java
        {
            namespace gcc = ignite::common::concurrent;

            /* --- Startup exception. --- */
            class JvmException : public std::exception {
                // No-op.
            };

            /* --- JNI method definitions. --- */
            struct JniMethod {
                char* name;
                char* sign;
                bool isStatic;

                JniMethod(const char* name, const char* sign, bool isStatic) {
                    this->name = const_cast<char*>(name);
                    this->sign = const_cast<char*>(sign);
                    this->isStatic = isStatic;
                }
            };

            /**
             * Heloper function to copy characters.
             *
             * @param src Source.
             * @return Result.
             */
            char* CopyChars(const char* src)
            {
                if (src)
                {
                    size_t len = strlen(src);
                    char* dest = new char[len + 1];
                    strcpy(dest, src);
                    *(dest + len) = 0;
                    return dest;
                }
                else
                    return NULL;
            }

            JniErrorInfo::JniErrorInfo() : code(IGNITE_JNI_ERR_SUCCESS), errCls(NULL), errMsg(NULL)
            {
                // No-op.
            }

            JniErrorInfo::JniErrorInfo(int code, const char* errCls, const char* errMsg) : code(code)
            {
                this->errCls = CopyChars(errCls);
                this->errMsg = CopyChars(errMsg);
            }

            JniErrorInfo::JniErrorInfo(const JniErrorInfo& other) : code(other.code)
            {
                this->errCls = CopyChars(other.errCls);
                this->errMsg = CopyChars(other.errMsg);
            }

            JniErrorInfo& JniErrorInfo::operator=(const JniErrorInfo& other)
            {
                if (this != &other)
                {
                    // 1. Create new instance, exception could occur at this point.
                    JniErrorInfo tmp(other);

                    // 2. Swap with temp.
                    int code0 = code;
                    char* errCls0 = errCls;
                    char* errMsg0 = errMsg;

                    code = tmp.code;
                    errCls = tmp.errCls;
                    errMsg = tmp.errMsg;

                    tmp.code = code0;
                    tmp.errCls = errCls0;
                    tmp.errMsg = errMsg0;
                }

                return *this;
            }

            JniErrorInfo::~JniErrorInfo()
            {
                if (errCls)
                    delete[] errCls;

                if (errMsg)
                    delete[] errMsg;
            }

            /**
             * Guard to ensure global reference cleanup.
             */
            class JniGlobalRefGuard
            {
            public:
                JniGlobalRefGuard(JNIEnv *e, jobject obj) : env(e), ref(obj)
                {
                    // No-op.
                }

                ~JniGlobalRefGuard()
                {
                    env->DeleteGlobalRef(ref);
                }

            private:
                /** Environment. */
                JNIEnv* env;

                /** Target reference. */
                jobject ref;

                IGNITE_NO_COPY_ASSIGNMENT(JniGlobalRefGuard)
            };

            const char* C_THROWABLE = "java/lang/Throwable";
            JniMethod M_THROWABLE_GET_MESSAGE = JniMethod("getMessage", "()Ljava/lang/String;", false);
            JniMethod M_THROWABLE_PRINT_STACK_TRACE = JniMethod("printStackTrace", "()V", false);

            const char* C_CLASS = "java/lang/Class";
            JniMethod M_CLASS_GET_NAME = JniMethod("getName", "()Ljava/lang/String;", false);

            const char* C_IGNITE_EXCEPTION = "org/apache/ignite/IgniteException";

            const char* C_PLATFORM_NO_CALLBACK_EXCEPTION = "org/apache/ignite/internal/processors/platform/PlatformNoCallbackException";

            const char* C_PLATFORM_TARGET = "org/apache/ignite/internal/processors/platform/PlatformTargetProxy";
            JniMethod M_PLATFORM_TARGET_IN_LONG_OUT_LONG = JniMethod("inLongOutLong", "(IJ)J", false);
            JniMethod M_PLATFORM_TARGET_IN_STREAM_OUT_LONG = JniMethod("inStreamOutLong", "(IJ)J", false);
            JniMethod M_PLATFORM_TARGET_IN_STREAM_OUT_OBJECT = JniMethod("inStreamOutObject", "(IJ)Ljava/lang/Object;", false);
            JniMethod M_PLATFORM_TARGET_IN_STREAM_OUT_STREAM = JniMethod("inStreamOutStream", "(IJJ)V", false);
            JniMethod M_PLATFORM_TARGET_IN_OBJECT_STREAM_OUT_OBJECT_STREAM = JniMethod("inObjectStreamOutObjectStream", "(ILjava/lang/Object;JJ)Ljava/lang/Object;", false);
            JniMethod M_PLATFORM_TARGET_OUT_STREAM = JniMethod("outStream", "(IJ)V", false);
            JniMethod M_PLATFORM_TARGET_OUT_OBJECT = JniMethod("outObject", "(I)Ljava/lang/Object;", false);
            JniMethod M_PLATFORM_TARGET_IN_STREAM_ASYNC = JniMethod("inStreamAsync", "(IJ)V", false);
            JniMethod M_PLATFORM_TARGET_IN_STREAM_OUT_OBJECT_ASYNC = JniMethod("inStreamOutObjectAsync", "(IJ)Ljava/lang/Object;", false);

            const char* C_PLATFORM_CALLBACK_UTILS = "org/apache/ignite/internal/processors/platform/callback/PlatformCallbackUtils";

            JniMethod M_PLATFORM_CALLBACK_UTILS_LOGGER_LOG = JniMethod("loggerLog", "(JILjava/lang/String;Ljava/lang/String;Ljava/lang/String;J)V", true);
            JniMethod M_PLATFORM_CALLBACK_UTILS_LOGGER_IS_LEVEL_ENABLED = JniMethod("loggerIsLevelEnabled", "(JI)Z", true);

            JniMethod M_PLATFORM_CALLBACK_UTILS_CONSOLE_WRITE = JniMethod("consoleWrite", "(Ljava/lang/String;Z)V", true);

            JniMethod M_PLATFORM_CALLBACK_UTILS_IN_LONG_OUT_LONG = JniMethod("inLongOutLong", "(JIJ)J", true);
            JniMethod M_PLATFORM_CALLBACK_UTILS_IN_LONG_LONG_LONG_OBJECT_OUT_LONG = JniMethod("inLongLongLongObjectOutLong", "(JIJJJLjava/lang/Object;)J", true);

            const char* C_PLATFORM_UTILS = "org/apache/ignite/internal/processors/platform/utils/PlatformUtils";
            JniMethod M_PLATFORM_UTILS_REALLOC = JniMethod("reallocate", "(JI)V", true);
            JniMethod M_PLATFORM_UTILS_ERR_DATA = JniMethod("errorData", "(Ljava/lang/Throwable;)[B", true);
            JniMethod M_PLATFORM_UTILS_GET_FULL_STACK_TRACE = JniMethod("getFullStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;", true);

            const char* C_PLATFORM_IGNITION = "org/apache/ignite/internal/processors/platform/PlatformIgnition";
            JniMethod M_PLATFORM_IGNITION_START = JniMethod("start", "(Ljava/lang/String;Ljava/lang/String;IJJ)V", true);
            JniMethod M_PLATFORM_IGNITION_INSTANCE = JniMethod("instance", "(Ljava/lang/String;)Lorg/apache/ignite/internal/processors/platform/PlatformProcessor;", true);
            JniMethod M_PLATFORM_IGNITION_ENVIRONMENT_POINTER = JniMethod("environmentPointer", "(Ljava/lang/String;)J", true);
            JniMethod M_PLATFORM_IGNITION_STOP = JniMethod("stop", "(Ljava/lang/String;Z)Z", true);
            JniMethod M_PLATFORM_IGNITION_STOP_ALL = JniMethod("stopAll", "(Z)V", true);

            /* STATIC STATE. */
            gcc::CriticalSection JVM_LOCK;
            gcc::CriticalSection CONSOLE_LOCK;
            JniJvm JVM;
            bool PRINT_EXCEPTION = false;
            std::vector<ConsoleWriteHandler> consoleWriteHandlers;

            /* HELPER METHODS. */

            /**
             * Throw exception to Java in case of missing callback pointer. It means that callback is not implemented in
             * native platform and Java -> platform operation cannot proceede further. As JniContext is not available at
             * this point, we have to obtain exception details from scratch. This is not critical from performance
             * perspective because missing handler usually denotes fatal condition.
             *
             * @param env JNI environment.
             */
            int ThrowOnMissingHandler(JNIEnv* env)
            {
                jclass cls = env->FindClass(C_PLATFORM_NO_CALLBACK_EXCEPTION);

                env->ThrowNew(cls, "Callback handler is not set in native platform.");

                return 0;
            }

            /**
             * Throw generic exception to Java in case of native exception. As JniContext is not available at
             * this point, we have to obtain exception details from scratch. This is not critical from performance
             * perspective because such exception is usually denotes fatal condition.
             *
             * @param env JNI environment.
             * @param msg Message.
             */
            void ThrowToJava(JNIEnv* env, const char* msg)
            {
                jclass cls = env->FindClass(C_IGNITE_EXCEPTION);

                env->ThrowNew(cls, msg);
            }

            char* StringToChars(JNIEnv* env, jstring str, int* len) {
                if (!str) {
                    *len = 0;
                    return NULL;
                }

                const char* strChars = env->GetStringUTFChars(str, 0);
                const int strCharsLen = env->GetStringUTFLength(str);

                char* strChars0 = new char[strCharsLen + 1];
                std::strcpy(strChars0, strChars);
                *(strChars0 + strCharsLen) = 0;

                env->ReleaseStringUTFChars(str, strChars);

                if (len)
                    *len = strCharsLen;

                return strChars0;
            }

            std::string JavaStringToCString(JNIEnv* env, jstring str, int* len)
            {
                char* resChars = StringToChars(env, str, len);

                if (resChars)
                {
                    std::string res = std::string(resChars, *len);

                    delete[] resChars;

                    return res;
                }
                else
                    return std::string();
            }

            jclass FindClass(JNIEnv* env, const char *name) {
                jclass res = env->FindClass(name);

                if (!res)
                    throw JvmException();

                jclass res0 = static_cast<jclass>(env->NewGlobalRef(res));

                env->DeleteLocalRef(res);

                return res0;
            }

            void DeleteClass(JNIEnv* env, jclass cls) {
                if (cls)
                    env->DeleteGlobalRef(cls);
            }

            void CheckClass(JNIEnv* env, const char *name)
            {
                jclass res = env->FindClass(name);

                if (!res)
                    throw JvmException();
            }

            jmethodID FindMethod(JNIEnv* env, jclass cls, JniMethod mthd) {
                jmethodID mthd0 = mthd.isStatic ?
                    env->GetStaticMethodID(cls, mthd.name, mthd.sign) : env->GetMethodID(cls, mthd.name, mthd.sign);

                if (!mthd0)
                    throw JvmException();

                return mthd0;
            }

            void AddNativeMethod(JNINativeMethod* mthd, JniMethod jniMthd, void* fnPtr) {
                mthd->name = jniMthd.name;
                mthd->signature = jniMthd.sign;
                mthd->fnPtr = fnPtr;
            }

            void JniJavaMembers::Initialize(JNIEnv* env) {
                c_Class = FindClass(env, C_CLASS);
                m_Class_getName = FindMethod(env, c_Class, M_CLASS_GET_NAME);

                c_Throwable = FindClass(env, C_THROWABLE);
                m_Throwable_getMessage = FindMethod(env, c_Throwable, M_THROWABLE_GET_MESSAGE);
                m_Throwable_printStackTrace = FindMethod(env, c_Throwable, M_THROWABLE_PRINT_STACK_TRACE);

                c_PlatformUtils = FindClass(env, C_PLATFORM_UTILS);
                m_PlatformUtils_getFullStackTrace = FindMethod(env, c_PlatformUtils, M_PLATFORM_UTILS_GET_FULL_STACK_TRACE);
            }

            void JniJavaMembers::Destroy(JNIEnv* env) {
                DeleteClass(env, c_Class);
                DeleteClass(env, c_Throwable);
                DeleteClass(env, c_PlatformUtils);
            }

            bool JniJavaMembers::WriteErrorInfo(JNIEnv* env, char** errClsName, int* errClsNameLen, char** errMsg,
				int* errMsgLen, char** stackTrace, int* stackTraceLen) {
                if (env && env->ExceptionCheck()) {
                    if (m_Class_getName && m_Throwable_getMessage) {
                        jthrowable err = env->ExceptionOccurred();

                        env->ExceptionClear();

                        jclass errCls = env->GetObjectClass(err);

                        jstring clsName = static_cast<jstring>(env->CallObjectMethod(errCls, m_Class_getName));
                        *errClsName = StringToChars(env, clsName, errClsNameLen);

                        jstring msg = static_cast<jstring>(env->CallObjectMethod(err, m_Throwable_getMessage));
                        *errMsg = StringToChars(env, msg, errMsgLen);

                        jstring trace = NULL;

                        if (c_PlatformUtils && m_PlatformUtils_getFullStackTrace) {
                            trace = static_cast<jstring>(env->CallStaticObjectMethod(c_PlatformUtils, m_PlatformUtils_getFullStackTrace, err));
                            *stackTrace = StringToChars(env, trace, stackTraceLen);
                        }

                        if (errCls)
                            env->DeleteLocalRef(errCls);

                        if (clsName)
                            env->DeleteLocalRef(clsName);

                        if (msg)
                            env->DeleteLocalRef(msg);

                        if (trace)
                            env->DeleteLocalRef(trace);

                        return true;
                    }
                    else {
                        env->ExceptionClear();
                    }
                }

                return false;
            }

            void JniMembers::Initialize(JNIEnv* env) {
                c_IgniteException = FindClass(env, C_IGNITE_EXCEPTION);

                c_PlatformIgnition = FindClass(env, C_PLATFORM_IGNITION);
                m_PlatformIgnition_start = FindMethod(env, c_PlatformIgnition, M_PLATFORM_IGNITION_START);
                m_PlatformIgnition_instance = FindMethod(env, c_PlatformIgnition, M_PLATFORM_IGNITION_INSTANCE);
                m_PlatformIgnition_environmentPointer = FindMethod(env, c_PlatformIgnition, M_PLATFORM_IGNITION_ENVIRONMENT_POINTER);
                m_PlatformIgnition_stop = FindMethod(env, c_PlatformIgnition, M_PLATFORM_IGNITION_STOP);
                m_PlatformIgnition_stopAll = FindMethod(env, c_PlatformIgnition, M_PLATFORM_IGNITION_STOP_ALL);

                c_PlatformTarget = FindClass(env, C_PLATFORM_TARGET);
                m_PlatformTarget_inLongOutLong = FindMethod(env, c_PlatformTarget, M_PLATFORM_TARGET_IN_LONG_OUT_LONG);
                m_PlatformTarget_inStreamOutLong = FindMethod(env, c_PlatformTarget, M_PLATFORM_TARGET_IN_STREAM_OUT_LONG);
                m_PlatformTarget_inStreamOutObject = FindMethod(env, c_PlatformTarget, M_PLATFORM_TARGET_IN_STREAM_OUT_OBJECT);
                m_PlatformTarget_outStream = FindMethod(env, c_PlatformTarget, M_PLATFORM_TARGET_OUT_STREAM);
                m_PlatformTarget_outObject = FindMethod(env, c_PlatformTarget, M_PLATFORM_TARGET_OUT_OBJECT);
                m_PlatformTarget_inStreamOutStream = FindMethod(env, c_PlatformTarget, M_PLATFORM_TARGET_IN_STREAM_OUT_STREAM);
                m_PlatformTarget_inObjectStreamOutObjectStream = FindMethod(env, c_PlatformTarget, M_PLATFORM_TARGET_IN_OBJECT_STREAM_OUT_OBJECT_STREAM);
                m_PlatformTarget_inStreamAsync = FindMethod(env, c_PlatformTarget, M_PLATFORM_TARGET_IN_STREAM_ASYNC);
                m_PlatformTarget_inStreamOutObjectAsync = FindMethod(env, c_PlatformTarget, M_PLATFORM_TARGET_IN_STREAM_OUT_OBJECT_ASYNC);

                c_PlatformUtils = FindClass(env, C_PLATFORM_UTILS);
                m_PlatformUtils_reallocate = FindMethod(env, c_PlatformUtils, M_PLATFORM_UTILS_REALLOC);
                m_PlatformUtils_errData = FindMethod(env, c_PlatformUtils, M_PLATFORM_UTILS_ERR_DATA);

                // Find utility classes which are not used from context, but are still required in other places.
                CheckClass(env, C_PLATFORM_NO_CALLBACK_EXCEPTION);
            }

            void JniMembers::Destroy(JNIEnv* env) {
                DeleteClass(env, c_IgniteException);
                DeleteClass(env, c_PlatformIgnition);
                DeleteClass(env, c_PlatformTarget);
                DeleteClass(env, c_PlatformUtils);
            }

            JniJvm::JniJvm() : jvm(NULL), javaMembers(JniJavaMembers()), members(JniMembers())
            {
                // No-op.
            }

            JniJvm::JniJvm(JavaVM* jvm, JniJavaMembers javaMembers, JniMembers members) :
                jvm(jvm), javaMembers(javaMembers), members(members)
            {
                // No-op.
            }

            JavaVM* JniJvm::GetJvm()
            {
                return jvm;
            }

            JniJavaMembers& JniJvm::GetJavaMembers()
            {
                return javaMembers;
            }

            JniMembers& JniJvm::GetMembers()
            {
                return members;
            }

            /**
             * Create JVM.
             */
            jint CreateJvm(char** opts, int optsLen, JavaVM** jvm, JNIEnv** env) {
                JavaVMOption* opts0 = new JavaVMOption[optsLen];

                for (int i = 0; i < optsLen; i++)
                    opts0[i].optionString = *(opts + i);

                JavaVMInitArgs args;

                args.version = JNI_VERSION_1_6;
                args.nOptions = optsLen;
                args.options = opts0;
                args.ignoreUnrecognized = 0;

                jint res = JNI_CreateJavaVM(jvm, reinterpret_cast<void**>(env), &args);

                delete[] opts0;

                return res;
            }

            void RegisterNatives(JNIEnv* env) {
                {
					JNINativeMethod methods[5];

                    int idx = 0;

                    AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_CONSOLE_WRITE, reinterpret_cast<void*>(JniConsoleWrite));

                    AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_LOGGER_LOG, reinterpret_cast<void*>(JniLoggerLog));
                    AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_LOGGER_IS_LEVEL_ENABLED, reinterpret_cast<void*>(JniLoggerIsLevelEnabled));

                    AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_IN_LONG_OUT_LONG, reinterpret_cast<void*>(JniInLongOutLong));
                    AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_IN_LONG_LONG_LONG_OBJECT_OUT_LONG, reinterpret_cast<void*>(JniInLongLongLongObjectOutLong));

                    jint res = env->RegisterNatives(FindClass(env, C_PLATFORM_CALLBACK_UTILS), methods, idx);

                    if (res != JNI_OK)
                        throw JvmException();
                }
            }

            JniContext::JniContext(JniJvm* jvm, JniHandlers hnds) : jvm(jvm), hnds(hnds) {
                // No-op.
            }

            JniContext* JniContext::Create(char** opts, int optsLen, JniHandlers hnds) {
                return Create(opts, optsLen, hnds, NULL);
            }

            void GetJniErrorMessage(std::string& errMsg, jint res)
            {
                switch (res)
                {
                    case JNI_ERR:
                        errMsg = "Unknown error (JNI_ERR).";
                        break;

                    case JNI_EDETACHED:
                        errMsg = "Thread detached from the JVM.";
                        break;

                    case JNI_EVERSION:
                        errMsg = "JNI version error.";
                        break;

                    case JNI_ENOMEM:
                        errMsg = "Could not reserve enough space for object heap. Check Xmx option.";
                        break;

                    case JNI_EEXIST:
                        errMsg = "JVM already created.";
                        break;

                    case JNI_EINVAL:
                        errMsg = "Invalid JVM arguments.";
                        break;

                    default:
                        errMsg = "Unexpected JNI_CreateJavaVM result.";
                        break;
                }
            }

            JniContext* JniContext::Create(char** opts, int optsLen, JniHandlers hnds, JniErrorInfo* errInfo)
            {
                // Acquire global lock to instantiate the JVM.
                JVM_LOCK.Enter();

                // Define local variables.
                JavaVM* jvm = NULL;
                JNIEnv* env = NULL;

                JniJavaMembers javaMembers;
                memset(&javaMembers, 0, sizeof(javaMembers));

                JniMembers members;
                memset(&members, 0, sizeof(members));

                JniContext* ctx = NULL;

                std::string errClsName;
                int errClsNameLen = 0;
                std::string errMsg;
                int errMsgLen = 0;
                std::string stackTrace;
                int stackTraceLen = 0;

                try {
                    if (!JVM.GetJvm())
                    {
                        // 1. Create JVM itself.
                        jint res = CreateJvm(opts, optsLen, &jvm, &env);

                        if (res == JNI_OK)
                        {
                            // 2. Populate members;
                            javaMembers.Initialize(env);
                            members.Initialize(env);

                            // 3. Register native functions.
                            RegisterNatives(env);

                            // 4. Create JNI JVM.
                            JVM = JniJvm(jvm, javaMembers, members);

                            char* printStack = getenv("IGNITE_CPP_PRINT_STACK");
                            PRINT_EXCEPTION = printStack && strcmp("true", printStack) == 0;
                        }
                        else
                        {
                            GetJniErrorMessage(errMsg, res);

                            errMsgLen = static_cast<int>(errMsg.length());
                        }
                    }

                    if (JVM.GetJvm())
                        ctx = new JniContext(&JVM, hnds);
                }
                catch (JvmException)
                {
                    char* errClsNameChars = NULL;
                    char* errMsgChars = NULL;
                    char* stackTraceChars = NULL;

                    // Read error info if possible.
                    javaMembers.WriteErrorInfo(env, &errClsNameChars, &errClsNameLen, &errMsgChars, &errMsgLen,
						&stackTraceChars, &stackTraceLen);

                    if (errClsNameChars) {
                        errClsName = errClsNameChars;

                        delete[] errClsNameChars;
                    }

                    if (errMsgChars)
                    {
                        errMsg = errMsgChars;

                        delete[] errMsgChars;
                    }

                    if (stackTraceChars)
                    {
                        stackTrace = stackTraceChars;

                        delete[] stackTraceChars;
                    }

                    // Destroy mmebers.
                    if (env) {
                        members.Destroy(env);
                        javaMembers.Destroy(env);
                    }

                    // Destroy faulty JVM.
                    if (jvm)
                        jvm->DestroyJavaVM();
                }

                // It safe to release the lock at this point.
                JVM_LOCK.Leave();

                // Notify err callback if needed.
                if (!ctx) {
                    if (errInfo) {
                        JniErrorInfo errInfo0(IGNITE_JNI_ERR_JVM_INIT, errClsName.c_str(), errMsg.c_str());

                        *errInfo = errInfo0;
                    }

                    if (hnds.error)
                        hnds.error(hnds.target, IGNITE_JNI_ERR_JVM_INIT, errClsName.c_str(), errClsNameLen,
                            errMsg.c_str(), errMsgLen, stackTrace.c_str(), stackTraceLen, NULL, 0);
                }

                return ctx;
            }

            int JniContext::Reallocate(long long memPtr, int cap) {
                JavaVM* jvm = JVM.GetJvm();

                JNIEnv* env;

                int attachRes = jvm->AttachCurrentThread(reinterpret_cast<void**>(&env), NULL);

                if (attachRes == JNI_OK)
                    AttachHelper::OnThreadAttach();
                else
                    return -1;

                env->CallStaticVoidMethod(JVM.GetMembers().c_PlatformUtils, JVM.GetMembers().m_PlatformUtils_reallocate, memPtr, cap);

                if (env->ExceptionCheck()) {
                    env->ExceptionClear();

                    return -1;
                }

                return 0;
            }

            void JniContext::Detach() {
                gcc::Memory::Fence();

                if (JVM.GetJvm()) {
                    JNIEnv* env;

                    JVM.GetJvm()->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);

                    if (env)
                        JVM.GetJvm()->DetachCurrentThread();
                }
            }

            void JniContext::IgnitionStart(char* cfgPath, char* name, int factoryId, long long dataPtr) {
                return IgnitionStart(cfgPath, name, factoryId, dataPtr, NULL);
            }

            void JniContext::IgnitionStart(char* cfgPath, char* name, int factoryId, long long dataPtr, JniErrorInfo* errInfo)
            {
                JNIEnv* env = Attach();

                jstring cfgPath0 = env->NewStringUTF(cfgPath);
                jstring name0 = env->NewStringUTF(name);

                env->CallStaticVoidMethod(
                    jvm->GetMembers().c_PlatformIgnition,
                    jvm->GetMembers().m_PlatformIgnition_start,
                    cfgPath0,
                    name0,
                    factoryId,
                    reinterpret_cast<long long>(&hnds),
                    dataPtr
                );

                ExceptionCheck(env, errInfo);
            }
            
            long long JniContext::IgnitionEnvironmentPointer(char* name)
            {
                return IgnitionEnvironmentPointer(name, NULL);
            }

            long long JniContext::IgnitionEnvironmentPointer(char* name, JniErrorInfo* errInfo)
            {
                JNIEnv* env = Attach();

                jstring name0 = env->NewStringUTF(name);

                long long res = env->CallStaticLongMethod(jvm->GetMembers().c_PlatformIgnition,
                    jvm->GetMembers().m_PlatformIgnition_environmentPointer, name0);

                ExceptionCheck(env, errInfo);

                return res;
            }

            bool JniContext::IgnitionStop(char* name, bool cancel)
            {
                return IgnitionStop(name, cancel, NULL);
            }

            bool JniContext::IgnitionStop(char* name, bool cancel, JniErrorInfo* errInfo)
            {
                JNIEnv* env = Attach();

                jstring name0 = env->NewStringUTF(name);

                jboolean res = env->CallStaticBooleanMethod(jvm->GetMembers().c_PlatformIgnition,
                    jvm->GetMembers().m_PlatformIgnition_stop, name0, cancel);

                ExceptionCheck(env, errInfo);

                return res != 0;
            }

            void JniContext::IgnitionStopAll(bool cancel)
            {
                return IgnitionStopAll(cancel, NULL);
            }

            void JniContext::IgnitionStopAll(bool cancel, JniErrorInfo* errInfo)
            {
                JNIEnv* env = Attach();

                env->CallStaticVoidMethod(jvm->GetMembers().c_PlatformIgnition,
                    jvm->GetMembers().m_PlatformIgnition_stopAll, cancel);

                ExceptionCheck(env, errInfo);
            }

            long long JniContext::TargetInLongOutLong(jobject obj, int opType, long long val, JniErrorInfo* err) {
                JNIEnv* env = Attach();

                long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformTarget_inLongOutLong, opType, val);

                ExceptionCheck(env, err);

                return res;
            }

            long long JniContext::TargetInStreamOutLong(jobject obj, int opType, long long memPtr, JniErrorInfo* err) {
                JNIEnv* env = Attach();

                long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutLong, opType, memPtr);

                ExceptionCheck(env, err);

                return res;
            }

            void JniContext::TargetInStreamOutStream(jobject obj, int opType, long long inMemPtr, long long outMemPtr, JniErrorInfo* err) {
                JNIEnv* env = Attach();

                env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutStream, opType, inMemPtr, outMemPtr);

                ExceptionCheck(env, err);
            }

           jobject JniContext::TargetInStreamOutObject(jobject obj, int opType, long long memPtr, JniErrorInfo* err) {
                JNIEnv* env = Attach();

                jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, opType, memPtr);

                ExceptionCheck(env, err);

                return LocalToGlobal(env, res);
            }

            jobject JniContext::TargetInObjectStreamOutObjectStream(jobject obj, int opType, void* arg, long long inMemPtr, long long outMemPtr, JniErrorInfo* err) {
                JNIEnv* env = Attach();

                jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_inObjectStreamOutObjectStream, opType, arg, inMemPtr, outMemPtr);

                ExceptionCheck(env, err);

                return LocalToGlobal(env, res);
            }

            void JniContext::TargetOutStream(jobject obj, int opType, long long memPtr, JniErrorInfo* err) {
                JNIEnv* env = Attach();

                env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_outStream, opType, memPtr);

                ExceptionCheck(env, err);
            }

            jobject JniContext::TargetOutObject(jobject obj, int opType, JniErrorInfo* err)
            {
                JNIEnv* env = Attach();

                jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_outObject, opType);

                ExceptionCheck(env, err);

                return LocalToGlobal(env, res);
            }

            void JniContext::TargetInStreamAsync(jobject obj, int opType, long long memPtr, JniErrorInfo* err) {
                JNIEnv* env = Attach();

                env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamAsync, opType, memPtr);

                ExceptionCheck(env, err);
            }

            jobject JniContext::TargetInStreamOutObjectAsync(jobject obj, int opType, long long memPtr, JniErrorInfo* err) {
                JNIEnv* env = Attach();

                jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObjectAsync, opType, memPtr);

                ExceptionCheck(env, err);

                return LocalToGlobal(env, res);
            }

            jobject JniContext::CacheOutOpQueryCursor(jobject obj, int type, long long memPtr, JniErrorInfo* err) {
                JNIEnv* env = Attach();

                jobject res = env->CallObjectMethod(
                    obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, type, memPtr);

                ExceptionCheck(env, err);

                return LocalToGlobal(env, res);
            }

            jobject JniContext::CacheOutOpContinuousQuery(jobject obj, int type, long long memPtr, JniErrorInfo* err) {
                JNIEnv* env = Attach();

                jobject res = env->CallObjectMethod(
                    obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, type, memPtr);

                ExceptionCheck(env, err);

                return LocalToGlobal(env, res);
            }

			jobject JniContext::Acquire(jobject obj)
            {
                if (obj) {

                    JNIEnv* env = Attach();

                    jobject obj0 = env->NewGlobalRef(obj);

                    ExceptionCheck(env);

                    return obj0;
                }

                return NULL;
            }

            void JniContext::Release(jobject obj) {
                if (obj)
                {
                    JavaVM* jvm = JVM.GetJvm();

                    if (jvm)
                    {
                        JNIEnv* env;

                        jint attachRes = jvm->AttachCurrentThread(reinterpret_cast<void**>(&env), NULL);

                        if (attachRes == JNI_OK)
                        {
                            AttachHelper::OnThreadAttach();

                            env->DeleteGlobalRef(obj);
                        }
                    }
                }
            }

            void JniContext::SetConsoleHandler(ConsoleWriteHandler consoleHandler) {
                if (!consoleHandler)
                    throw std::invalid_argument("consoleHandler can not be null");

                CONSOLE_LOCK.Enter();

                consoleWriteHandlers.push_back(consoleHandler);

                CONSOLE_LOCK.Leave();
            }

            int JniContext::RemoveConsoleHandler(ConsoleWriteHandler consoleHandler) {
                if (!consoleHandler)
                    throw std::invalid_argument("consoleHandler can not be null");

                CONSOLE_LOCK.Enter();

                int oldSize = static_cast<int>(consoleWriteHandlers.size());

                consoleWriteHandlers.erase(remove(consoleWriteHandlers.begin(), consoleWriteHandlers.end(),
                    consoleHandler), consoleWriteHandlers.end());

                int removedCnt = oldSize - static_cast<int>(consoleWriteHandlers.size());

                CONSOLE_LOCK.Leave();

                return removedCnt;
            }

            void JniContext::ThrowToJava(char* msg) {
                JNIEnv* env = Attach();

                env->ThrowNew(jvm->GetMembers().c_IgniteException, msg);
            }

            void JniContext::DestroyJvm() {
                jvm->GetJvm()->DestroyJavaVM();
            }

            /**
             * Attach thread to JVM.
             */
            JNIEnv* JniContext::Attach() {
                JNIEnv* env;

                jint attachRes = jvm->GetJvm()->AttachCurrentThread(reinterpret_cast<void**>(&env), NULL);

                if (attachRes == JNI_OK)
                    AttachHelper::OnThreadAttach();
                else {
                    if (hnds.error)
                        hnds.error(hnds.target, IGNITE_JNI_ERR_JVM_ATTACH, NULL, 0, NULL, 0, NULL, 0, NULL, 0);
                }

                return env;
            }

            void JniContext::ExceptionCheck(JNIEnv* env) {
                ExceptionCheck(env, NULL);
            }

            void JniContext::ExceptionCheck(JNIEnv* env, JniErrorInfo* errInfo)
            {
                if (env->ExceptionCheck()) {
                    jthrowable err = env->ExceptionOccurred();

                    if (PRINT_EXCEPTION)
                        env->CallVoidMethod(err, jvm->GetJavaMembers().m_Throwable_printStackTrace);

                    env->ExceptionClear();

                    // Get error class name and message.
                    jclass cls = env->GetObjectClass(err);

                    jstring clsName = static_cast<jstring>(env->CallObjectMethod(cls, jvm->GetJavaMembers().m_Class_getName));
                    jstring msg = static_cast<jstring>(env->CallObjectMethod(err, jvm->GetJavaMembers().m_Throwable_getMessage));
                    jstring trace = static_cast<jstring>(env->CallStaticObjectMethod(jvm->GetJavaMembers().c_PlatformUtils, jvm->GetJavaMembers().m_PlatformUtils_getFullStackTrace, err));

                    env->DeleteLocalRef(cls);

                    int clsNameLen;
                    std::string clsName0 = JavaStringToCString(env, clsName, &clsNameLen);

                    int msgLen;
                    std::string msg0 = JavaStringToCString(env, msg, &msgLen);

                    int traceLen;
                    std::string trace0 = JavaStringToCString(env, trace, &traceLen);

                    if (errInfo)
                    {
                        JniErrorInfo errInfo0(IGNITE_JNI_ERR_GENERIC, clsName0.c_str(), msg0.c_str());

                        *errInfo = errInfo0;
                    }

                    // Get error additional data (if any).
                    jbyteArray errData = static_cast<jbyteArray>(env->CallStaticObjectMethod(
                        jvm->GetMembers().c_PlatformUtils, jvm->GetMembers().m_PlatformUtils_errData, err));

                    if (errData)
                    {
                        jbyte* errBytesNative = env->GetByteArrayElements(errData, NULL);

                        int errBytesLen = env->GetArrayLength(errData);

                        if (hnds.error)
                            hnds.error(hnds.target, IGNITE_JNI_ERR_GENERIC, clsName0.c_str(), clsNameLen, msg0.c_str(),
								msgLen, trace0.c_str(), traceLen, errBytesNative, errBytesLen);

                        env->ReleaseByteArrayElements(errData, errBytesNative, JNI_ABORT);
                    }
                    else
                    {
                        if (hnds.error)
                            hnds.error(hnds.target, IGNITE_JNI_ERR_GENERIC, clsName0.c_str(), clsNameLen, msg0.c_str(),
								msgLen, trace0.c_str(), traceLen, NULL, 0);
                    }

                    env->DeleteLocalRef(err);
                }
            }

            /**
             * Convert local reference to global.
             */
            jobject JniContext::LocalToGlobal(JNIEnv* env, jobject localRef) {
                if (localRef) {
                    jobject globalRef = env->NewGlobalRef(localRef);

                    env->DeleteLocalRef(localRef); // Clear local ref irrespective of result.

                    if (!globalRef)
                        ExceptionCheck(env);

                    return globalRef;
                }
                else
                    return NULL;
            }

            JNIEXPORT void JNICALL JniConsoleWrite(JNIEnv *env, jclass cls, jstring str, jboolean isErr) {
                CONSOLE_LOCK.Enter();

                if (consoleWriteHandlers.size() > 0) {
                    ConsoleWriteHandler consoleWrite = consoleWriteHandlers.at(0);

                    const char* strChars = env->GetStringUTFChars(str, 0);
                    const int strCharsLen = env->GetStringUTFLength(str);

                    consoleWrite(strChars, strCharsLen, isErr);

                    env->ReleaseStringUTFChars(str, strChars);
                }

                CONSOLE_LOCK.Leave();
            }

            JNIEXPORT void JNICALL JniLoggerLog(JNIEnv *env, jclass cls, jlong envPtr, jint level, jstring message, jstring category, jstring errorInfo, jlong memPtr) {
                int messageLen;
                char* messageChars = StringToChars(env, message, &messageLen);

                int categoryLen;
                char* categoryChars = StringToChars(env, category, &categoryLen);

                int errorInfoLen;
                char* errorInfoChars = StringToChars(env, errorInfo, &errorInfoLen);

                IGNITE_SAFE_PROC(env, envPtr, LoggerLogHandler, loggerLog, level, messageChars, messageLen, categoryChars, categoryLen, errorInfoChars, errorInfoLen, memPtr);

                if (messageChars)
                    delete[] messageChars;

                if (categoryChars)
                    delete[] categoryChars;

                if (errorInfoChars)
                    delete[] errorInfoChars;
            }

            JNIEXPORT jboolean JNICALL JniLoggerIsLevelEnabled(JNIEnv *env, jclass cls, jlong envPtr, jint level) {
                IGNITE_SAFE_FUNC(env, envPtr, LoggerIsLevelEnabledHandler, loggerIsLevelEnabled, level);
            }

            JNIEXPORT jlong JNICALL JniInLongOutLong(JNIEnv *env, jclass cls, jlong envPtr, jint type, jlong val) {
                IGNITE_SAFE_FUNC(env, envPtr, InLongOutLongHandler, inLongOutLong, type, val);
            }

            JNIEXPORT jlong JNICALL JniInLongLongLongObjectOutLong(JNIEnv *env, jclass cls, jlong envPtr, jint type, jlong val1, jlong val2, jlong val3, jobject arg) {
                IGNITE_SAFE_FUNC(env, envPtr, InLongLongLongObjectOutLongHandler, inLongLongLongObjectOutLong, type, val1, val2, val3, arg);
            }
        }
    }
}
