//
// Created by #Suyghur, on 2021/06/09.
//



#include <jni.h>
#include <toolkit.h>
#include <comm_map.h>
#include <params_kit.h>
#include <request_kit.h>
#include <md5/md5.h>
#include "include/logger.h"
#include "aes/aes_utils.h"

static void InitSdkDrive(JNIEnv *env, jobject thiz, jobject context) {
    CommMap::GetInstance()->Init(env, context);
    Logger::is_debug = ParamsKit::GetDebugModel(env, context);
}

static void SetParam(JNIEnv *env, jobject thiz, jstring key, jstring value) {
    std::string key_ = ToolKit::JString2String(env, key);
    std::string value_ = ToolKit::JString2String(env, value);
    if (key_ == "device_id") {
        if (value_ == CommMap::GetInstance()->comm_params["android_id"].asString()) {
            CommMap::GetInstance()->comm_params["id_type"] = 1;
        } else {
            CommMap::GetInstance()->comm_params["id_type"] = 0;
        }
    }
    CommMap::GetInstance()->comm_params[key_] = value_;
}

static jstring GetParam(JNIEnv *env, jobject thiz, jstring key) {
    std::string key_ = ToolKit::JString2String(env, key);
    return env->NewStringUTF(CommMap::GetInstance()->comm_params[key_].asString().c_str());
}

static jstring InvokeJob(JNIEnv *env, jobject thiz, jobject context, jstring key, jstring data) {
    const char *key_ = env->GetStringUTFChars(key, JNI_FALSE);
    const char *data_ = env->GetStringUTFChars(data, JNI_FALSE);

    //添加公共参数
    Json::Value root = ToolKit::ToJsonObject(data_);
    root["common"] = CommMap::GetInstance()->comm_params;

    Logger::D(env, "请求参数 : " + ToolKit::ToJsonString(root));

    char *p = AesUtils::Encrypt(ToolKit::ToJsonString(root).c_str(), reinterpret_cast<const uint8_t *>(key_));
    jstring result = ToolKit::GetJString(env, p);
    env->ReleaseStringUTFChars(key, key_);
    env->ReleaseStringUTFChars(data, data_);
    free(p);
    return result;
}

static jstring ParseJob(JNIEnv *env, jobject thiz, jobject context, jstring key, jstring data) {
    const char *key_ = env->GetStringUTFChars(key, JNI_FALSE);
    const char *data_ = env->GetStringUTFChars(data, JNI_FALSE);
    char *raw = AesUtils::Decrypt(data_, reinterpret_cast<const uint8_t *>(key_));
    Logger::D(env, raw);
    jstring result = ToolKit::GetJString(env, raw);
    env->ReleaseStringUTFChars(key, key_);
    env->ReleaseStringUTFChars(data, data_);
    free(raw);
    return result;
}

static jstring GetComm(JNIEnv *env, jobject thiz, jobject context) {
    Json::Value root;
    root["common"] = CommMap::GetInstance()->comm_params;
    jstring data = ToolKit::GetJString(env, ToolKit::ToJsonString(root).c_str());
    return data;
}


static JNINativeMethod gMethod[] = {
        {"initSdkDrive", "(Landroid/content/Context;)V",                                                      (void *) InitSdkDrive},
        {"setParam",     "(Ljava/lang/String;Ljava/lang/String;)V",                                           (void *) SetParam},
        {"getParam",     "(Ljava/lang/String;)Ljava/lang/String;",                                            (void *) GetParam},
        {"invokeJob",    "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void *) InvokeJob},
        {"parseJob",     "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void *) ParseJob},
        {"getComm",      "(Landroid/content/Context;)Ljava/lang/String;",                                     (void *) GetComm},

};

extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env = nullptr;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        return JNI_ERR;
    }
    jclass clz = env->FindClass("cn/yyxx/eyuangame/core/impl/SdkDrive");
    if (env->RegisterNatives(clz, gMethod, sizeof(gMethod) / sizeof(gMethod[0])) < 0) {
        return JNI_ERR;
    }
    return JNI_VERSION_1_6;
}