//
// Created by Ht on 2020/7/13.
//

#ifndef JMUFISUNIT_QAYNCHTTPSERVER_H
#define JMUFISUNIT_QAYNCHTTPSERVER_H

#include <exlib/http/QHttpServer.h>

namespace jedge {


    using QASyncHttpHandler = std::function<bool (ChannelOperator& opr, const httplib::Request &httprequest,
            qlibc::QData &request, qlibc::QData &response)>;

    using QASyncHttpPostHandler = std::function<bool (ChannelOperator& opr, qlibc::QData &response)>;

#define bindHttpPath(targetObj, patten, method) \
    targetObj.addPathHandler(DATA_CHANNEL_HTTP, (patten),  [this](ChannelOperator& opr, const httplib::Request &httprequest, \
            qlibc::QData &request,qlibc::QData &response) { \
        this->method(opr, httprequest, request, response); \
    })

#define bindHttpPattern(targetObj, patten, method) \
    targetObj.addPatternHandler(DATA_CHANNEL_HTTP, (patten),  [this](ChannelOperator& opr, const httplib::Request &httprequest, \
            qlibc::QData &request,qlibc::QData &response) -> bool { \
        return this->method(opr, httprequest, request, response); \
    })

#define bindHttpDefault(targetObj, method) \
    bindHttpPattern(targetObj, "/**" ,method)

        /**
         * 绑定：  http://host/baseuri/...到一个指定的method
         */
#define bindHttpBaseDefault(targetObj, baseUri, method) \
    bindHttpPath(targetObj, StringUtils::formatString("/%s", key.c_str()) ,method);\
    bindHttpPattern(targetObj, StringUtils::formatString("/%s/**", key.c_str()) ,method)

    class JE_API QASyncHttpServer :
            public QHttpServer,
            public MgDataChannel {
    protected:
        qlibc::QObjectMemoryPool<MgbusRequest, MESSAGE_POOL_SIZE> mg_req_pool_;
        QASyncHttpPostHandler*   post_handler_ = nullptr;
    public:
        explicit QASyncHttpServer(ChannelOperator &opr) :
                QHttpServer(opr),
                MgDataChannel(opr), mg_req_pool_([]()->MgbusRequest*{ return new MgbusRequest;})
                {}

        const string &objId() override;

        ~QASyncHttpServer() override {
            delete post_handler_;
        };

        void addPathHandler(const string& srcChn, const string& path, const QASyncHttpHandler& handler);

        void addPatternHandler(const string& srcChn, const string& pattern, const QASyncHttpHandler& handler);

        bool postRawMessage(qlibc::QData &message) override;

        void removePatherHandler(const string &pattern);

        void addASyncRawHandler(QHttpHandlerMap& target, const string& srcChn, const string& key, const QASyncHttpHandler& handler, bool ordered = false);

        void setASyncPostHandler(const QASyncHttpPostHandler& handler);
    };

    //用于mgbus holder的子类添加http接口时使用
#define declareHttpUriHandlers(httpServer) \
        void appendMessageHandlers(const std::string &dataChannel, const QStringList &pattern_list) override { \
            for(const auto& path : pattern_list){ \
                (httpServer).addPatternHandler(DATA_CHANNEL_HTTP, path,  \
                        [&dataChannel](ChannelOperator& opr, const httplib::Request &httprequest, qlibc::QData  &request, qlibc::QData &response) ->bool { \
                    return opr.postAsyncMessage(DATA_CHANNEL_HTTP, dataChannel, request); \
                }); \
            }\
            MgBusHolder::appendMessageHandlers(dataChannel, pattern_list);\
        }

}
#endif //JMUFISUNIT_QAYNCHTTPSERVER_H
