// @@@ START COPYRIGHT @@@
//
// 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.
//
// @@@ END COPYRIGHT @@@

#include "LmRoutineJavaObj.h"
#include "org_trafodion_sql_udr_UDR.h"

LmResult LmRoutineJavaObj::setRuntimeInfo(
     const char   *qid,
     int           totalNumInstances,
     int           myInstanceNum,
     ComDiagsArea *da)
{
  LmResult result = LM_OK;
  JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_;
  jstring jqid = jni->NewString((const jchar *) qid, strlen(qid));

  // call the Java method that will ultimately call the user code
  jni->CallVoidMethod(
       udrInvokeObjectG_,
       (jmethodID) getLM()->setRuntimeInfoId_,
       jqid,
       (jint) totalNumInstances,
       (jint) myInstanceNum);

  if (jni->ExceptionOccurred())
    {
      getLM()->exceptionReporter_->checkJVMException(da, 0);
      if (da)
        {
          // an error without a diagnostic message from Java
          *da << DgSqlCode(-LME_OBJECT_INTERFACE_ERROR)
              << DgString0(getNameForDiags())
              << DgString1("runtime")
              << DgString2("LmRoutineJavaObj::setRuntimeInfo()")
              << DgString3("Exception in JNI call");
        }
      result = LM_ERR;
    }

  // delete input parameter objects
  jni->DeleteLocalRef(jqid);

  return result;
}

LmResult LmRoutineJavaObj::invokeRoutineMethod(
     /* IN */     tmudr::UDRInvocationInfo::CallPhase phase,
     /* IN */     const char   *serializedInvocationInfo,
     /* IN */     Int32         invocationInfoLen,
     /* OUT */    Int32        *invocationInfoLenOut,
     /* IN */     const char   *serializedPlanInfo,
     /* IN */     Int32         planInfoLen,
     /* IN */     Int32         planNum,
     /* OUT */    Int32        *planInfoLenOut,
     /* IN */     char         *inputRow,
     /* IN */     Int32         inputRowLen,
     /* OUT */    char         *outputRow,
     /* IN */     Int32         outputRowLen,
     /* IN/OUT */ ComDiagsArea *da)
{
  LmResult result = LM_OK;
  JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_;
  if (inputRowLen >= 0)
    inputRowLen_ = inputRowLen;
  if (outputRowLen >= 0)
    outputRowLen_ = outputRowLen;

  jbyteArray jii = jni->NewByteArray((jint) invocationInfoLen);
  jbyteArray jpi = jni->NewByteArray((jint) planInfoLen);
  jbyteArray jir = jni->NewByteArray((jint) inputRowLen_);

  jni->SetByteArrayRegion(jii,
                          (jsize) 0,
                          (jsize) invocationInfoLen,
                          (const jbyte *) serializedInvocationInfo);
  jni->SetByteArrayRegion(jpi,
                          (jsize) 0,
                          (jsize) planInfoLen,
                          (const jbyte *) serializedPlanInfo);
  jni->SetByteArrayRegion(jir,
                          (jsize) 0,
                          (jsize) inputRowLen_,
                          (const jbyte *) inputRow);

  // call the Java method that will ultimately call the user code
  jobject jniResult = jni->CallObjectMethod(
       udrInvokeObjectG_,
       (jmethodID) getLM()->routineMethodInvokeId_,
       (jint) phase,
       jii,
       jpi,
       (jint) planNum,
       jir);

  if (jniResult == NULL || jni->ExceptionOccurred())
    {
      // this catches any exceptions other than UDRException
      // thrown in the Java code
      getLM()->exceptionReporter_->checkJVMException(da, 0);
      if (da && da->mainSQLCODE() >= 0)
        {
          // an error without a diagnostic message from Java
          char buf[4];
          snprintf(buf, sizeof(buf), "%d", static_cast<int>(phase));
          *da << DgSqlCode(-LME_OBJECT_INTERFACE_ERROR)
              << DgString0(getNameForDiags())
              << DgString1(buf)
              << DgString2("LmRoutineJavaObj::invokeRoutineMethod()")
              << DgString3("JNI call returned a NULL object");
        }
      result = LM_ERR;
    }

  // delete input parameter objects
  jni->DeleteLocalRef(jii);
  jni->DeleteLocalRef(jpi);
  jni->DeleteLocalRef(jir);

  // clear return info from any previous calls
  if (returnedIIL_)
    {
      jni->DeleteLocalRef(returnedIIL_);
      returnedIIL_ = NULL;
    }
  if (returnedPIL_)
    {
      jni->DeleteLocalRef(returnedPIL_);
      returnedPIL_ = NULL;
    }

  iiLen_ = piLen_ = 0;

  if (result == LM_OK)
    {
      // retrieve returned information
      jint returnStatus = jni->GetIntField(
           jniResult, 
           (jfieldID) getLM()->returnInfoStatusField_);

      if (returnStatus != 0)
        {
          getLM()->exceptionReporter_->processJavaObjException(
               jniResult,
               returnStatus,
               static_cast<int>(phase),
               "LmRoutineJavaObj::invokeRoutineMethod()",
               getNameForDiags(),
               da);
          result = LM_ERR;
        }
      else
        {
          returnedIIL_ = static_cast<jbyteArray>(
               jni->GetObjectField(
                    jniResult,
                    (jfieldID) getLM()->returnInfoRIIField_));
          returnedPIL_ = static_cast<jbyteArray>(
               jni->GetObjectField(
                    jniResult,
                    (jfieldID) getLM()->returnInfoRPIField_));

          if (returnedIIL_)
            iiLen_ = jni->GetArrayLength(returnedIIL_);

          if (returnedPIL_)
            piLen_ = jni->GetArrayLength(returnedPIL_);
        }

      if (phase == tmudr::UDRInvocationInfo::RUNTIME_WORK_CALL &&
          result == LM_OK)
        {
          SQLUDR_Q_STATE qs = SQLUDR_Q_EOD;
          // emit the EOD (end of data) for the result table
          (*emitRowPtr_)(NULL,0,&qs);
        }
    }
  jni->DeleteLocalRef(jniResult);

  if (invocationInfoLenOut)
    *invocationInfoLenOut = static_cast<Int32>(iiLen_);

  if (planInfoLenOut)
    *planInfoLenOut = static_cast<Int32>(piLen_);

  return result;
}

LmResult LmRoutineJavaObj::getRoutineInvocationInfo(
     /* IN/OUT */ char         *serializedInvocationInfo,
     /* IN */     Int32         invocationInfoMaxLen,
     /* OUT */    Int32        *invocationInfoLenOut,
     /* IN/OUT */ char         *serializedPlanInfo,
     /* IN */     Int32         planInfoMaxLen,
     /* IN */     Int32         planNum,
     /* OUT */    Int32        *planInfoLenOut,
     /* IN/OUT */ ComDiagsArea *da)
{
  JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_;
  LmResult result = LM_OK;

  // return the serialized invocation info
  if (returnedIIL_)
    {
      if (invocationInfoMaxLen < iiLen_ && serializedInvocationInfo)
        {
          if (da)
            *da << DgSqlCode(-LME_OBJECT_INTERFACE_ERROR)
                << DgString0(getNameForDiags())
                << DgString1("unknown")
                << DgString2("getRoutineInvocationInfo()")
                << DgString3("Buffer too short for invocation info");
          iiLen_ = 0;
          result = LM_ERR;
        }
      else if (serializedInvocationInfo)
        {
          jbyte * returnedIIChar = jni->GetByteArrayElements(returnedIIL_, NULL);
          str_cpy_all(serializedInvocationInfo,
                      reinterpret_cast<const char *>(returnedIIChar),
                      iiLen_);
          jni->ReleaseByteArrayElements(returnedIIL_, returnedIIChar, JNI_ABORT);
        }
      jni->DeleteLocalRef(returnedIIL_);
      returnedIIL_ = NULL;
    }

  if (invocationInfoLenOut)
    *invocationInfoLenOut = iiLen_;
  iiLen_ = 0;

  // return the serialized plan info
  if (returnedPIL_)
    {
      if (planInfoMaxLen < piLen_ && serializedPlanInfo)
        {
          if (da)
            *da << DgSqlCode(-LME_OBJECT_INTERFACE_ERROR)
                << DgString0(getNameForDiags())
                << DgString1("unknown")
                << DgString2("getRoutineInvocationInfo()")
                << DgString3("Buffer too short for plan info");
          piLen_ = 0;
          result = LM_ERR;
        }
      else if (serializedPlanInfo)
        {
          jbyte * returnedPIChar = jni->GetByteArrayElements(returnedPIL_, NULL);
          str_cpy_all(serializedPlanInfo,
                      reinterpret_cast<const char *>(returnedPIChar),
                      piLen_);
          jni->ReleaseByteArrayElements(returnedPIL_, returnedPIChar, JNI_ABORT);
        }
      jni->DeleteLocalRef(returnedPIL_);
      returnedPIL_ = NULL;
    }

  if (planInfoLenOut)
    *planInfoLenOut = piLen_;
  piLen_ = 0;

  return result;
}

LmResult LmRoutineJavaObj::setFunctionPtrs(
     SQLUDR_GetNextRow getNextRowPtr,
     SQLUDR_EmitRow emitRowPtr,
     ComDiagsArea *da)
{
  JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_;
  LmResult result = LM_OK;

  // save a local copy to be able to emit the EOD (end of data)
  emitRowPtr_ = emitRowPtr;

  const JNINativeMethod methods[2] = {
    { const_cast<char *>("SpInfoGetNextRowJava"),
      const_cast<char *>("([BILorg/trafodion/sql/udr/UDR$QueueStateInfo;)V"),
      reinterpret_cast<void *>(jniGetNextRowPtr_) },
    { const_cast<char *>("SpInfoEmitRowJava"),
      const_cast<char *>("([BILorg/trafodion/sql/udr/UDR$QueueStateInfo;)V"),
      reinterpret_cast<void *>(jniEmitRowPtr_) }
  };

  // use this method to register the native methods, which are already
  // loaded in the executable, not need to load a separate DLL
  jint returnStatus = jni->RegisterNatives(
       reinterpret_cast<jclass>(getLM()->udrClass_),
       methods,
       static_cast<jint>(sizeof(methods)/sizeof(methods[0])));
       
  if (returnStatus != 0 || jni->ExceptionOccurred())
    {
      getLM()->exceptionReporter_->insertDiags(
           da,
           -LME_INTERNAL_ERROR,
           ": Error in LmRoutineJavaObj::setFunctionPtrs()");

      if (da)
        {
          char buf2[80];
          snprintf(buf2, sizeof(buf2), "Return status %d from JNI call", returnStatus);

          *da << DgSqlCode(-LME_OBJECT_INTERFACE_ERROR)
              << DgString0(getNameForDiags())
              << DgString1("runtime initial")
              << DgString2("LmRoutineJavaObj::setFunctionPtrs()")
              << DgString3(buf2);
        }
      result = LM_ERR;
    }

  return result;
}

void LmRoutineJavaObj::setJNIFunctionPtrs(void *jniGetNextRowPtr,
                                          void *jniEmitRowPtr)
{
  jniGetNextRowPtr_ = jniGetNextRowPtr;
  jniEmitRowPtr_ = jniEmitRowPtr;
}

void LmRoutineJavaObj::setRowLengths(int inputRowLen,
                                     int outputRowLen)
{
  inputRowLen_  = inputRowLen;
  outputRowLen_ = outputRowLen;
}

LmRoutineJavaObj::LmRoutineJavaObj(
     const char   *sqlName,
     const char   *externalName,
     const char   *librarySqlName,
     ComRoutineTransactionAttributes transactionAttrs,
     ComRoutineSQLAccess sqlAccessMode,
     ComRoutineExternalSecurity externalSecurity,
     Int32    routineOwnerId,
     const char   *serializedInvocationInfo,
     int           invocationInfoLen,
     const char   *serializedPlanInfo,
     int           planInfoLen,
     LmLanguageManagerJava *lm,
     jobject       udrObject,
     LmContainer  *container,
     ComDiagsArea *diagsArea) : LmRoutineJava(sqlName,
                                              externalName,
                                              librarySqlName,
                                              0,
                                              NULL,
                                              0,
                                              NULL,
                                              COM_STYLE_JAVA_OBJ,
                                              transactionAttrs,
                                              sqlAccessMode,
                                              externalSecurity,
                                              routineOwnerId,
                                              NULL,
                                              0,
                                              0,
                                              NULL,
                                              NULL,
                                              NULL,
                                              lm,
                                              (LmHandle) NULL,
                                              container,
                                              diagsArea),
                                udrObjectG_(NULL),
                                udrInvokeObjectG_(NULL),
                                returnedIIL_(NULL),
                                returnedPIL_(NULL),
                                iiLen_(0),
                                piLen_(0),
                                inputRowLen_(-1),
                                outputRowLen_(-1),
                                emitRowPtr_(NULL),
                                jniGetNextRowPtr_(NULL),
                                jniEmitRowPtr_(NULL)
{
  JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_;
  jbyteArray jii = jni->NewByteArray((jint) invocationInfoLen);
  jbyteArray jpi = NULL;
  jobject udrInvokeObject = NULL;

  jni->SetByteArrayRegion(jii,
                          (jsize) 0,
                          (jsize) invocationInfoLen,
                          (const jbyte *) serializedInvocationInfo);

  if (planInfoLen > 0)
    {
      jpi = jni->NewByteArray((jint) planInfoLen);

      jni->SetByteArrayRegion(jpi,
                              (jsize) 0,
                              (jsize) planInfoLen,
                              (const jbyte *) serializedPlanInfo);
    }

  if (!jni->ExceptionOccurred())
    // Do a JNI call to allocate an LmUDRObjMethodInvoke object
    udrInvokeObject = jni->CallStaticObjectMethod(
         (jclass)    getLM()->lmObjMethodInvokeClass_,
         (jmethodID) getLM()->makeNewObjId_,
         udrObject,
         jii,
         jpi);

  jni->DeleteLocalRef(jii);
  if (planInfoLen > 0)
    jni->DeleteLocalRef(jpi);

  if (udrInvokeObject != NULL && !jni->ExceptionOccurred())
    {
      // create global references for these objects, they will
      // last as long as the LmRoutineJavaObj
      udrObjectG_ = jni->NewGlobalRef(udrObject);
      jni->DeleteLocalRef(udrObject);
      udrInvokeObjectG_ = jni->NewGlobalRef(udrInvokeObject);
      jni->DeleteLocalRef(udrInvokeObject);
    }

  if (udrObjectG_ == NULL || udrInvokeObjectG_ == NULL || jni->ExceptionOccurred())
    {
      getLM()->exceptionReporter_->insertDiags(
           diagsArea,
           -LME_INTERNAL_ERROR,
           ": Error in LmRoutineJavaObj::LmRoutineJavaObj()");
    }
}

LmRoutineJavaObj::~LmRoutineJavaObj()
{
  JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_;

  if (udrObjectG_ != NULL)
    jni->DeleteGlobalRef(udrObjectG_);
  if (udrInvokeObjectG_ != NULL)
    jni->DeleteGlobalRef(udrInvokeObjectG_);
  if (returnedIIL_)
    jni->DeleteLocalRef(returnedIIL_);
  if (returnedPIL_)
    jni->DeleteLocalRef(returnedPIL_);
}

ComBoolean LmRoutineJavaObj::isValid() const
{
  return udrObjectG_ != NULL && udrInvokeObjectG_ != NULL;
}
