//
// Created by lixingchen on 2019/12/30.
//

#ifdef U_PLATFORM_ANDROID

#ifndef COOKENGINE_COOKMENU_H
#define COOKENGINE_COOKMENU_H

#include "../../include/CookMenuBase.h"
#include "../../include/CookVariant.h"
#include "../../include/CookLog.h"
#include "../../include/CookFunItem.h"

using namespace ns_catering;

jclass m_jItemClz = 0;
jobject m_callback = 0;

class CCookMenu : public ICookMenuBase
{
public:
    CCookMenu(JavaVM* jvm, JNIEnv* env, jobject callback)
            : ICookMenuBase()
            , m_jvm(jvm)
            //, m_callback(callback)
    {
        COOK_LOG_INFO("call %s, env=%x, this=%ld", __FUNCTION__, env, this);

        // 获取funitem class
        if(0 == m_jItemClz)
        {
            jclass jitemClz = env->FindClass("com/utcloud/cookengine/CookFunItem");
            if (0 == jitemClz)
            {
                COOK_LOG_ERROR("can not get class of funitem.");
            }
            else
            {
                COOK_LOG_INFO("can get class of funitem.");
            }
            m_jItemClz =  (jclass )env->NewGlobalRef(jitemClz);
            env->DeleteLocalRef(jitemClz);
        }

        if(0 == m_callback) {
            m_callback = env->NewGlobalRef(callback);
        }
     }

    ~CCookMenu()
    {
/*
        if (m_jvm != 0 && m_callback != 0)
        {
            JNIEnv *env;
            if(m_jvm->AttachCurrentThread(&env, NULL)  !=  JNI_OK)
            {
                return;
            }
            env->DeleteLocalRef(m_callback);
            env->DeleteLocalRef(m_jItemClz);
        }
*/
        COOK_LOG_INFO("call %s!!!!!!!!!!!!!!!!!!!!!!!!!!", __FUNCTION__);
    }


    virtual bool GetVar(const std::string& taskId, long trueProductId, const std::string& productFieldName, CCookVariant* pRetValue)
    {
        // TODO :
        COOK_LOG_INFO("call %s!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", __FUNCTION__);

        return true;
    }

    virtual bool SetVar(const std::string& taskId, long trueProductId, const std::string& productFieldName, const CCookVariant* pVarValue)
    {
        // TODO:
        return true;
    }

    virtual bool RunAppFun(const std::string& taskId, int iCmdId, int iCurStep, int iTotleStep, const std::vector<CCookFunItem*>& funItemList)
    {
        JNIEnv *env;
        //Attach主线程
        if(m_jvm->AttachCurrentThread(&env, NULL)  !=  JNI_OK)
        {
            return false;
        }
        COOK_LOG_INFO("call %s, env=%x, taskid=%s, curStep=%d, totleStep=%d, this=%x",
                      __FUNCTION__, env, taskId.c_str(), iCurStep, iTotleStep, this);

        jobjectArray jFunItemList = cfunitemsToJfunitems(env, m_jItemClz, funItemList);
        // TODO:调用回调，并将值释放
        jstring jTaskId = cstringToJString(env, taskId);
        jboolean  bRet = callBooleanMethod (env, m_callback,  "onRunAppFun", "(JLjava/lang/String;III[Lcom/utcloud/cookengine/CookFunItem;)Z",
                                            (jlong)this, jTaskId, iCmdId, iCurStep, iTotleStep, jFunItemList);
        // 值的释放
        env->DeleteLocalRef(jTaskId);
        freeJobjectarray(env, jFunItemList);

        m_jvm->DetachCurrentThread();
        return bRet;
    }

    virtual bool OnEndTask(const std::string& taskId)
    {
        COOK_LOG_INFO("call %s, taskid=%s, this=%x", __FUNCTION__, taskId.c_str(), this);
        JNIEnv *env;
        //Attach主线程
        if(m_jvm->AttachCurrentThread(&env, NULL)  !=  JNI_OK)
        {
            return false;
        }
        // 调用回调函数
        jstring jTaskId = cstringToJString(env, taskId);
        jboolean  bRet = callBooleanMethod(env, m_callback, "onEndTask", "(JLjava/lang/String;)Z", (jlong)this, jTaskId);
        env->DeleteLocalRef(jTaskId);
        m_jvm->DetachCurrentThread();

        return bRet;
    }

    virtual bool OnEndCookMenu(bool bSuccess)
    {
        COOK_LOG_INFO("call %s, bSuccess=%d, this=%x", __FUNCTION__, bSuccess, this);
        JNIEnv *env;
        //Attach主线程
        if(m_jvm->AttachCurrentThread(&env, NULL)  !=  JNI_OK)
        {
            return false;
        }
        // 调用回调函数
        jboolean  bRet = callBooleanMethod(env, m_callback, "onEndInstance", "(JZ)Z", (jlong)this, bSuccess);
        m_jvm->DetachCurrentThread();
        return bRet;
    }

private:
    JavaVM* m_jvm;
    //static jclass m_jItemClz;
    //static jobject m_callback;
};

#endif //COOKENGINE_COOKMENU_H

#endif // U_PLATFORM_ANDROID