// 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 "Clr2JavaImpl.h"

namespace Org {
	namespace Apache {
		namespace REEF {
			namespace Driver {
				namespace Bridge {
					namespace Clr2java {
						private ref class ManagedLog {
						internal:
							static BridgeLogger^ LOGGER = BridgeLogger::GetLogger("<C++>");
						};

						ActiveContextClr2Java::ActiveContextClr2Java(JNIEnv *env, jobject jobjectActiveContext) {
							ManagedLog::LOGGER->LogStart("ActiveContextClr2Java::ActiveContextClr2Java");
							pin_ptr<JavaVM*> pJavaVm = &_jvm;
							if (env->GetJavaVM(pJavaVm) != 0) {
								ManagedLog::LOGGER->LogError("Failed to get JavaVM", nullptr);
							}

							_jobjectActiveContext = reinterpret_cast<jobject>(env->NewGlobalRef(jobjectActiveContext));

							jclass jclassActiveContext = env->GetObjectClass(_jobjectActiveContext);
							jmethodID jmidGetContextId = env->GetMethodID(jclassActiveContext, "getContextId", "()Ljava/lang/String;");
							_jstringId = CommonUtilities::CallGetMethodNewGlobalRef<jstring>(env, _jobjectActiveContext, jmidGetContextId);
							jmethodID jmidGetParentContextId = env->GetMethodID(jclassActiveContext, "getParentContextId", "()Ljava/lang/String;");
							_jstringParentId = CommonUtilities::CallGetMethodNewGlobalRef<jstring>(env, _jobjectActiveContext, jmidGetParentContextId);
							_jstringEvaluatorId = CommonUtilities::GetJObjectEvaluatorId(env, _jobjectActiveContext, jclassActiveContext);

							ManagedLog::LOGGER->LogStop("ActiveContextClr2Java::ActiveContextClr2Java");
						}

						ActiveContextClr2Java::~ActiveContextClr2Java() {
							this->!ActiveContextClr2Java();
						}

						ActiveContextClr2Java::!ActiveContextClr2Java() {
							JNIEnv *env = RetrieveEnv(_jvm);
							if (_jobjectActiveContext != NULL) {
								env->DeleteGlobalRef(_jobjectActiveContext); 
							}

							if (_jstringId != NULL) {
								env->DeleteGlobalRef(_jstringId);
							}

							if (_jstringEvaluatorId != NULL) {
								env->DeleteGlobalRef(_jstringEvaluatorId);
							}
						}

						void ActiveContextClr2Java::SubmitTask(String^ taskConfigStr) {
							ManagedLog::LOGGER->LogStart("ActiveContextClr2Java::SubmitTask");
							JNIEnv *env = RetrieveEnv(_jvm);
							jclass jclassActiveContext = env->GetObjectClass(_jobjectActiveContext);
							jmethodID jmidSubmitTask = env->GetMethodID(jclassActiveContext, "submitTaskString", "(Ljava/lang/String;)V");

							if (jmidSubmitTask == NULL) {
								ManagedLog::LOGGER->Log("jmidSubmitTask is NULL");
								return;
							}
							env->CallObjectMethod(
								_jobjectActiveContext,
								jmidSubmitTask,
								JavaStringFromManagedString(env, taskConfigStr));
							ManagedLog::LOGGER->LogStop("ActiveContextClr2Java::SubmitTask");
						}

						void ActiveContextClr2Java::SubmitContext(String^ contextConfigStr) {
							SubmitContextAndService(contextConfigStr, nullptr);
						}

						void ActiveContextClr2Java::SubmitContextAndService(String^ contextConfigStr, String^ serviceConfigStr) {
							JNIEnv *env = RetrieveEnv(_jvm);
							jclass jclassActiveContext = env->GetObjectClass(_jobjectActiveContext);
							jmethodID jmidSubmitContext = 
								env->GetMethodID(jclassActiveContext, "submitContextStringAndServiceString", "(Ljava/lang/String;Ljava/lang/String;)V");

							if (jmidSubmitContext == NULL) {
								ManagedLog::LOGGER->Log("jmidSubmitContextStringAndServiceString is NULL");
								return;
							}

							const jstring serviceConfigJavaStr = 
								serviceConfigStr == nullptr ? NULL : JavaStringFromManagedString(env, serviceConfigStr);

							env->CallObjectMethod(
								_jobjectActiveContext,
								jmidSubmitContext,
								JavaStringFromManagedString(env, contextConfigStr),
								serviceConfigJavaStr);
						}

						void ActiveContextClr2Java::OnError(String^ message) {
							JNIEnv *env = RetrieveEnv(_jvm);
							HandleClr2JavaError(env, message, _jobjectActiveContext);
						}

						void ActiveContextClr2Java::Close() {
							ManagedLog::LOGGER->LogStart("ActiveContextClr2Java::Close");
							JNIEnv *env = RetrieveEnv(_jvm);
							jclass jclassActiveContext = env->GetObjectClass(_jobjectActiveContext);
							jmethodID jmidClose = env->GetMethodID(jclassActiveContext, "close", "()V");

							if (jmidClose == NULL) {
								ManagedLog::LOGGER->Log("jmidClose is NULL");
								return;
							}
							env->CallObjectMethod(
								_jobjectActiveContext,
								jmidClose);
							ManagedLog::LOGGER->LogStop("ActiveContextClr2Java::Close");
						}

						String^ ActiveContextClr2Java::GetParentId() {
							JNIEnv *env = RetrieveEnv(_jvm);
							return ManagedStringFromJavaString(env, _jstringParentId);
						}

						String^ ActiveContextClr2Java::GetId() {
							JNIEnv *env = RetrieveEnv(_jvm);
							return ManagedStringFromJavaString(env, _jstringId);
						}

						String^ ActiveContextClr2Java::GetEvaluatorId() {
							JNIEnv *env = RetrieveEnv(_jvm);
							return ManagedStringFromJavaString(env, _jstringEvaluatorId);
						}

						IEvaluatorDescriptor^ ActiveContextClr2Java::GetEvaluatorDescriptor() {
							ManagedLog::LOGGER->LogStart("ActiveContextClr2Java::GetEvaluatorDescriptor");
							return CommonUtilities::RetrieveEvaluatorDescriptor(_jobjectActiveContext, _jvm);
						}

						void ActiveContextClr2Java::SendMessage(array<byte>^ message) {
							ManagedLog::LOGGER->LogStart("ActiveContextClr2Java::SendMessage");
							JNIEnv *env = RetrieveEnv(_jvm);
							jclass jclassActiveContext = env->GetObjectClass(_jobjectActiveContext);
							jmethodID jmidSendMessage = env->GetMethodID(jclassActiveContext, "sendMessage", "([B)V");

							if (jmidSendMessage == NULL) {
								ManagedLog::LOGGER->Log("jmidSendMessage is NULL");
								return;
							}

							env->CallObjectMethod(
								_jobjectActiveContext,
								jmidSendMessage,
								JavaByteArrayFromManagedByteArray(env, message));

							ManagedLog::LOGGER->LogStop("ActiveContextClr2Java::SendMessage");
						}
					}
				}
			}
		}
	}
}