//
// Created by Ht on 2020/4/24.
//

#ifndef TESTBIN_JMQTTMESSAGEDELIVER_H
#define TESTBIN_JMQTTMESSAGEDELIVER_H

#include <mutex>
#include <unordered_map>
#include <functional>

#include <qlibc/qlibc.h>
#include <mgbus/ChannelOperator.h>

namespace jedge {

    static const char* _default_topic_key = "_@df";

    using QMqttRawHandler    = std::function<bool (ChannelOperator& o, const std::string& t, const byte b[], int l)>;
    using QMqttHandler       = std::function<bool (ChannelOperator& o, const std::string& t, qlibc::QData& m)>;
    using QMqttUriRspHandler    = std::function<bool (ChannelOperator& o, const std::string& u, qlibc::QData& m)>;
    using QMqttUriReqHandler    = std::function<bool (qlibc::QData& r, ChannelOperator& o, const std::string& u, qlibc::QData& q)>;
    using QMqttResponseSender   = std::function<void(const qlibc::QData& p)>;

    class JE_API QMqttMessageDeliver {

    private:
        qlibc::QSharedObjectHolder<QMqttUriRspHandler>
                    mUriRspHandlers;
        qlibc::QSharedObjectHolder<QMqttUriReqHandler>
                    mUriReqHandlers;
        qlibc::QSharedObjectHolder<QMqttHandler>
                    mTopicHandlers;
        qlibc::QSharedObjectHolder<QMqttRawHandler>
                    mTopicRawHandlers;

        ChannelOperator& opr_;
        QMqttResponseSender*
                         mRspSender_ = nullptr;

    public:
        explicit QMqttMessageDeliver(jedge::ChannelOperator& sender) : opr_(sender) {};

        virtual ~QMqttMessageDeliver();

        int handleMessage(const std::string &topic, const unsigned char* buff, int buff_len);

        void appendTopicHandler(const QMqttHandler& handler, const std::string &topic = _default_topic_key);      //topic为空时，为默认handler，可能屏蔽所有uri的handler

        void appendTopicHandler(const QMqttRawHandler& handler, const std::string &topic = _default_topic_key);   //topic为空时，为默认handler，可能屏蔽所有uri的handler

        void appendUriHandler(const std::string &uri, const QMqttUriReqHandler& handler);

        void appendUriHandler(const std::string &uri, const QMqttUriRspHandler& handler);

        void setRespnoseSender(const jedge::QMqttResponseSender& sender) ;

    protected:
        bool handleResponse(qlibc::QData& message);

        bool handleRequest(qlibc::QData& message);

    };
}

#endif //TESTBIN_Jconst MQTTMESSAGEDELIV&ER_H
