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

#ifndef LIBDEVCPP_MGBUSSERVICE_H
#define LIBDEVCPP_MGBUSSERVICE_H

#include "MgDataChannel.h"
#include "ChannelOperator.h"
#include "MgbusMessageUtil.h"
#include "MgBusHolder.h"
#include <qlibc/qlibc.h>

namespace jedge {

    using MgbusCommandResultHandler = JE_API
                std::function <void(const std::string &src,
                    const std::string &cmd,
                    const qlibc::QData &param)>;

    class JE_API MgBusService :
            public MgService ,
            public MgTriggerManagerOperator {
    protected:
        qlibc::QSharedObjectHolder<MgbusCommandResultHandler>*
                mgbus_service_commands_ = nullptr;
    public:
        explicit MgBusService(jedge::MgBusHolder &opr, const std::string &name, const qlibc::QData &config)
            : MgService (opr, name, config, true), MgTriggerManagerOperator(dynamic_cast<ChannelOperator&>(opr)) {}

        ~MgBusService() override = default;


        qlibc::QSharedObjectHolder<MgbusCommandResultHandler>& getCommandHandlerPoot() {
            RECURSIVE_LOCK(service_mutex_);
            if(mgbus_service_commands_ == nullptr) {
                mgbus_service_commands_ = new qlibc::QSharedObjectHolder<MgbusCommandResultHandler>();
            }
            return *mgbus_service_commands_;
        }

        void releaseMgbusCommandHandlers() {
            if(mgbus_service_commands_ != nullptr) {
                mgbus_service_commands_->releaseAll();
                delete mgbus_service_commands_;
                mgbus_service_commands_ = nullptr;
            }
        }

        virtual bool handleServiceCommand(const std::string &src,
                                          const std::string &cmd,
                                          const qlibc::QData &param);

        void preparePattern() override;

        //检查module是否存在某功能
        bool checkModuleFunction(const std::string & module, const std::string & functionName);

    protected:
        bool postServiceCommand(const std::string &svc, const std::string &cmd, qlibc::QData &req);

        void addCommandHandler(const std::string &cmd, const MgbusCommandResultHandler& handler);

        void removeCommandHandler(const std::string &cmd);

        virtual jedge::MgBusHolder *getHolder() {
            return dynamic_cast<jedge::MgBusHolder*>(&operator_);
        }

        auto getTrigerService() -> MgTriggerManager* override;

        void registerFunction(const string &func);

        bool checkEvent(qlibc::QData &msg, qlibc::QData *rsp);

        bool checkHandler(qlibc::QData &msg, qlibc::QData *rsp);
    };

#define HandleMgbusCommandResult(func) \
    auto self_##func = getSelfRef();\
    addCommandHandler(#func, [this, self_##func](const std::string &src,\
        const std::string &cmd,\
        const qlibc::QData &message){ return cmd_##func(this,src,cmd,message);})

#define DefaultHandleMgbusCommandResult(hdlr) \
    auto self_##hdlr = getSelfRef();\
    addCommandHandler(jedge::JEDGE_DEFAULT_SERVICE_COMMAND, [this,self_##hdlr](const std::string &src,\
        const std::string &cmd,\
        const qlibc::QData &message){ return cmd_##hdlr(this,src,cmd,message);})

//这样设计的目的，是为了避免修改实现的头文件，简化代码结构。
#define ImplementMgbusCommandResultHandler(func,svc,s,c,m) \
        void cmd_##func(jedge::MgBusService* svc,\
        const std::string &s,\
        const std::string &c,\
        const qlibc::QData &m)

}

#endif //LIBDEVCPP_MGBUSSERVICE_H
