//
// Created by Ht on 2022/8/29.
//

#ifndef INC_1_LIBDEVCPP_QGAWANJAPLUGINENTRY_H
#define INC_1_LIBDEVCPP_QGAWANJAPLUGINENTRY_H

#include "../../src/plugin/QGaCypherPluginEntry.h"
#include "../../src/QGADataPool.h"
#include <mqtt/Base64.h>

namespace jedge {

    class QBytesFastDecoder : public qlibc::QData {
    public:
        void loadBytesDecoder(const std::string &decoderFn) {
            QLog("Loading decoder : %s", decoderFn.c_str());
        }

        void decode(qlibc::QData& ret, const std::string &methodKey, const std::string &devType, const std::string &hexString) {
            QHLogR("Getting result from : %s, type %s, key: %s", hexString.c_str(), devType.c_str(), methodKey.c_str());
            ret.putString("data", hexString);
            //TODO::从字节流解码到json结构
        }

        void decode(qlibc::QData& ret, const std::string &devType, const std::string &hexString) {
            decode(ret, "uri", devType,hexString);
        }
    };

    class QBytesFastEncoder {
    public:
        void loadBytesEncoder(const std::string &encoderFn) {
            QLog("Loading encoder : %s", encoderFn.c_str());
        }

        void encode(std::string &hexString, const std::string &devType, const std::string &uriKey, const qlibc::QData& src) {
            //TODO::编码器,从json编码到字节流
            QHLogR("Getting result from : %s, type %s, key: %s", hexString.c_str(), devType.c_str(), uriKey.c_str());
        }

        void encode(std::string &hexString, const std::string &devType, const qlibc::QData& src) {
            encode(hexString, devType, src.getString("uri"), src);
        }
    };

    class JE_API  QGaWanjiaanPluginEntry :
            public QGaCypherPluginEntry {
    protected:
        QBytesFastDecoder bytesDecoder;
        QBytesFastEncoder bytesEncoder;
        std::mutex decode_mutex_;

    public:
        explicit QGaWanjiaanPluginEntry(std::string name, std::string type = "cypher", int ver = 0) :
                jedge::QGaCypherPluginEntry(std::move(name), std::move(type), ver) {
        }

        void setDataPool(QGADataPool &pool) override {
            QGaCypherPluginEntry::setDataPool(pool);
            bytesDecoder.loadBytesDecoder(FileUtils::contactFilename(data_pool_->getCacheFilePath(),"decoder.json"));
            bytesEncoder.loadBytesEncoder(FileUtils::contactFilename(data_pool_->getCacheFilePath(),"encoder.json"));
            //用户自定义的函数:
            // (1) encodeHexFromMsg
            data_pool_->bindUserDefinedGAOFunction("encodeHexFromMsg",
                                                   [this](Json::Value& ret, QStringList& funcParams, const qlibc::QData& msg)->bool {
                                                       //从json到字节流的消息编码,并形成String的字符串后返回
                                                       auto devType = msg.getString("device_class");
                                                       std::string str;
                                                       bytesEncoder.encode(str, devType, msg);
                                                       ret = str;
                                                       return true;
                                                   });
        }

        QGaCypherPluginEntry *duplication(const string &name) override {
            auto* dup = new QGaWanjiaanPluginEntry(name, typeKey_, ver_);
            dup->sn_ = sn_;
            return dup;
        }

        bool handleMqttMessage(const string &topic, QData &msg) override {
            auto deviceTarget = StringUtils::getSubStrAfter(topic, '/',-1);
            msg.putString("deviceId", deviceTarget);
            //"data" : "/ylx"
            auto data = msg.removeString("data");
            auto *tmp = data_pool_->getOperator().getBlankMessage();
            {
                SINGLE_LOCK(decode_mutex_);
                auto targetLen = Base64_decodeLength(data.c_str(), data.size());
                auto* bytes = new QByte[targetLen];
                int realSize = (int)Base64_decode(bytes, targetLen, data.c_str(), data.size());
                std::string hexString;
                NumberUtils::bytesToHexStr(bytes,realSize, hexString);
                //调用自定义Bytes2Json解码器
                bytesDecoder.decode(*tmp, deviceTarget, hexString);
            }
            //获取方法，如何获得uri
            const auto *uri = "";
            msg.putString("uri", uri);
            msg.put("payload",tmp->asValue());
            data_pool_->getOperator().releaseMessage(tmp);
            //自定义字节流的解码器
            return QGaCypherPluginEntry::handleMqttMessage(topic, msg);
        }
    };
}


#endif //INC_1_LIBDEVCPP_QGAWANJAPLUGINENTRY_H
