//
// Created by Ht on 2021/4/17.
//

#ifndef INC_0_LIBDEVCPP_QMGBUSMODULESERVER_H
#define INC_0_LIBDEVCPP_QMGBUSMODULESERVER_H

#include <mgbus/MgBusHolder.h>

namespace jedge {

    using ShutDownTask = std::function<void(void)>;

    class JE_API QMgbusModule :
            public MgServerIntf,
            public MgBusHolder {
    protected:
        SocketMode mg_mode;
        ShutDownTask* shutdown_handler = nullptr;
    public:
        explicit QMgbusModule(const qlibc::QData &initConfig, const std::string &name, SocketMode mode = typeUDP,
                              const httplib::RThreadPool& pool = nullptr, const qlibc::QRTimerEngine& engine = nullptr,
                              const qlibc::QRTriggerEngine &tr_engine = nullptr) :
                MgBusHolder(initConfig, name, pool, engine, tr_engine), mg_mode(mode) {
        };

        ~QMgbusModule() override {
            delete (shutdown_handler);
            shutdown_handler = nullptr;
            clearLogToFile();
            clearLogToLocalNetwork();
        }

        bool isActive() override {
            return isRunning();
        }

        SocketMode socketMode() {
            return mg_mode;
        }

        bool start(const qlibc::QData &config) override {
            if(!isRunning()) {
                setupLogToLocalNetwork();
                setupLogToFile();
                prepareMgBusHolder(config);
                afterServiceInit();
                if(!doServerStart(config)) {
                    return false;
                }
                auto mode = config.getString(vkey_config_mgbus_type);
                if(mode=="tcp") mg_mode = typeTCP;
                startMgBusClient(mg_mode);
                MgServerIntf::start(config);
                QLog("%s Start ok.", name().c_str());
//                resetAutoCloser([this](){
//                    if(isRunning())
//                        shutdown();
//                });
            }
            return isRunning();
        }

        void resetAutoCloser(const ShutDownTask& closer) {
            delete shutdown_handler;
            shutdown_handler = new ShutDownTask (closer);
        }

        virtual void doServerShutdown()  {
            if(shutdown_handler!=nullptr) {
                (*shutdown_handler)();
            }
        };

        void setShuwdownTask(const ShutDownTask& task){
            if(shutdown_handler==nullptr)
                shutdown_handler = new ShutDownTask;
            *shutdown_handler = task;
        }

        virtual bool doServerStart(const qlibc::QData& data) { return true; };

        void shutdown() override {
            if(isRunning()) {
                auto server = mg_host;
                auto port = mg_port;
                closeMgBusClient();
                doServerShutdown();
                QLog("%s is down (from server %s:%d).", name().c_str(), server.c_str(), port);
                MgServerIntf::shutdown();
            }
        }

    };


}

#endif //INC_0_LIBDEVCPP_QMGBUSMODULESERVER_H
