//
// Created by Ht on 2019/8/2.
//

#ifndef JSONPROTOCOL_JEDPANALYZER_H
#define JSONPROTOCOL_JEDPANALYZER_H

#include <qlibc/QDataMemoryPool.h>
#include <qlibc/cmd/JCArgNode.h>
#include "JRDpBaseObj.h"
#include "JRByteTransfer.h"
#include "JRPackage.h"
#include "JRDpCommandDecoder.h"
#include "JRPackageDecorder.h"
#include "JEDPBaseMsgPacker.h"

/**
 *      解析或生成的方式，主要是针对Package通过@@common字段的定义进行解包，
 *          如果有transfer数据，优先进行转义处理，
 *          然后是对Command进行解析，
 *              解析其ParamData，
 *                  如果有paramTable，则完成Table的转换处理，最后返回目标对象。
 */

namespace jedp {

    static const char* vkey_rule_common = "@@common";
    static const char* vkey_rule_transfer = "@transfer";

    static const char* vkey_rule_transfer_range = "target";
    static const char* vkey_rule_transfer_list = "list";
    static const char* vkey_rule_transfer_sign = "sign";
    static const char* vkey_rule_transfer_na = "na";
    static const char cval_trans_default = 0x12;
    static const char* vkey_rule_transfer_action = "action";


    class JE_API JEDPAnalyzer :
        public JRDpBaseObj {
    private:
        using QJedpDbgCmdHandler = std::function<void(qlibc::JCArgNode &node)>;
        //消息池
        qlibc::QObjectMemoryPool<JRPackage, 8>  package_pool_;
        std::string path_;

        JRByteTransfer* mByteTransfer = nullptr;
        JRPackageDecorder* mPckgDecorder = nullptr;
        JEDPUserDecoderHandlerTable      mUddhTable;         // 用户自定义解码函数表
        JEDPUserEncoderHandlerTable      mUdehTable;         // 用户自定义编码函数表
        qlibc::QPObjectHolder<QJedpDbgCmdHandler> cmds_;

    protected:
        //生成字段解码器
        bool buildCommandDecorders();

        JRPackage *getBlankPackage();

        //解码消息
        JRPackage *dePackage(const unsigned char *buff, size_t bufflen);

        void releasePackage(JRPackage *pPackage);

        void buildDebugCommandHandlers();

    public:
        JEDPAnalyzer();
        explicit JEDPAnalyzer(QData& data);
        ~JEDPAnalyzer() override;

        void addExternalJedpEncoder(qlibc::QData& encoderDef, const std::string& templName = "");

        //协议自适应
        bool fitProtocol(const unsigned char *buff, size_t bufflen);

        //去消息数据转换
        bool deTransferBytes(const QByte *buff, size_t bufflen, QRByte &newbuff, size_t &newlen);

        //消息解码
        bool buildJRJsonMessage(qlibc::QData &targetMsg,const unsigned char *buff, size_t bufflen, bool preTrans = false);
        //指定路径解码器的消息解码
        bool buildJRJsonMessage(qlibc::QData &targetMsg, const unsigned char *targetBuff, size_t bufflen,const std::string& path);
        //生成消息
        bool encodeJRJsonMessage(qlibc::QData &sentMsg, unsigned char **targetBuff, size_t &bufflen);

        //根据路径生成消息
        bool encodeJRJsonMessage(qlibc::QData &sentMsg, unsigned char **targetBuff, size_t &bufflen,
                                 const std::string& path);

        //根据入口消息和简单路径,生成准确的调用路径
        void makeDecoderPath(std::string& fullPath, const std::string& path, qlibc::QData& req);

        bool isValid();

        void setupMessagePacker(JEDPBaseMsgPacker *packer);

        void addUserDefineEncoder(const string &funcKey, const JEDPEncoderHandler &handler);

        void addUserDefineDecoder(const string &funcKey, const JEDPDecoderHandler &handler);

        const std::string& getDataBaseKey() {
            return mPckgDecorder->getDataBaseKey();
        }

        //执行对jedp的调试命令:
        // list / load / clear / insert / remove
        void handleDebugCommand(const string &cmd, qlibc::JCArgNode &node);

        inline void setRulePath(const std::string& path) {
            path_ = path;
        }

        inline const std::string& getRulePath() {
            return path_;
        }

        void listJedpItems(const std::string& grepKey, Json::Value* logs = nullptr);
    };

    using JEDPRAnalyzer = std::shared_ptr<JEDPAnalyzer>;
}


#endif //JSONPROTOCOL_JEDPANALYZER_H
