//
// Created by Ht on 2022/10/20.
//

#ifndef IOT_EDGE_VDALNEW_JEVDALCOMMONSERVICE_H
#define IOT_EDGE_VDALNEW_JEVDALCOMMONSERVICE_H

#include <src/VdalDeviceContext.h>
#include "VdalDefaultService.h"

namespace  jedge {

    class JE_API MogaAndroidService : public MgBusService {
    protected:
        VdalDeviceContext& vdd_context_;
        QVdalDevicePortR moga_pool_;
    public:
    explicit MogaAndroidService(MgBusHolder &opr, const string &name, const qlibc::QData &config) :
            MgBusService(opr, name, config),
            vdd_context_(VdalDeviceContext::getInstance()) {
            moga_pool_ = vdd_context_.findPort("moga");
        }

        void preparePattern() override {
            prepareSelfBind;
            bindHandler(response);
            bindHandler(provisionRsp);
        }

        bool response(qlibc::QData &req, qlibc::QData *response) {
            string model_name = operator_.name();
            model_name = StringUtils::toUpperCase(model_name);
            QInfo("%s-Moga received:%s", operator_.name().c_str(),req.toJSONString().c_str());
            if(moga_pool_!=nullptr) {
                req.removeKey("uri");
                moga_pool_->handleMogaControlMessage(req, response);
            }
            OkPRsp(response);
            return true;
        }
        bool provisionRsp(qlibc::QData &req, qlibc::QData *response) {
            string model_name = operator_.name();
            model_name = StringUtils::toUpperCase(model_name);
            QInfo("%s-Moga received:%s", operator_.name().c_str(),req.toJSONString().c_str());
            if(moga_pool_!=nullptr) {
                req.removeKey("uri");
                moga_pool_->handleMogaConfigMessage(req, response);
            }
            OkPRsp(response);
            return true;
        }
    };

    class VdalConfigService : public MgBusService {
    public:
        explicit VdalConfigService(jedge::MgBusHolder& opr, const std::string& name, const qlibc::QData& config):
                MgBusService(opr, name, config) {
        }

        bool query(qlibc::QData &req, qlibc::QData *resp) {
            auto *service = dynamic_cast<VdalDefaultService*>(getHolder().findService("device"));
            if(service!= nullptr)
                service->queryDevice(req, resp);
            else {
                FailPRspMsg(resp, "Fail to work on device servide.");
            }
            return true;
        }

        void preparePattern() override {
            prepareSelfBind;
            bindHandler(query);
        }
    };

    class VdalDebugService : public MgBusService {
    protected:
        VdalDeviceContext& context_;
    public:
        explicit VdalDebugService(jedge::MgBusHolder& opr, const std::string& name, const qlibc::QData& config):
                MgBusService(opr, name, config), context_(VdalDeviceContext::getInstance()) {
        }

        //串口调试命令
        bool controlSerial(qlibc::QData &req, qlibc::QData *resp) {
            //Debug
            auto port = req.getString("$port"); //执行哪一个port
            auto cmd = req.getString("$debug"); //命令
            auto p = context_.findPort(port);
            if(p== nullptr) {
                FailPRspMsgFmt(resp,"Unknown port : %s", port.c_str());
                return true;
            }
            if(!p->handleRemoteSerialDebugCommand(cmd, req, resp))
                FailPRspMsgFmt(resp, "Fail handle serial command : %s", cmd.c_str());
            return true;
        }

        //端口控制?
        bool controlPort(qlibc::QData &req, qlibc::QData *resp) {
            //Debug
            auto cmd = req.getString("$debug");     //命令
            if(!context_.handleCommandorCommand(cmd, req, resp))
                FailPRspMsgFmt(resp, "Fail handle serial command : %s", cmd.c_str());
            return true;
        }

        //调试控制指令?
        bool controlDebugger(qlibc::QData &req, qlibc::QData *resp) {
            //Debug
            auto port = req.getString("$port");     //执行哪一个port
            auto cmd = req.getString("$debug");     //命令
            auto p = context_.findPort(port);
            if(p== nullptr) {
                FailPRspMsgFmt(resp,"Unknown port : %s", port.c_str());
                return true;
            }
            if(!p->handleDebuggerCommand(cmd, req, resp))
                FailPRspMsgFmt(resp, "Fail handle debugger command : %s", cmd.c_str());
            return true;
        }

        //设备控制调试
        bool controlDevice(qlibc::QData &req, qlibc::QData *resp) {
            //Debug
            auto port = req.getString("$port");     //执行哪一个port
            auto cmd = req.getString("$debug");     //命令
            auto p = context_.findPort(port);
            if(p== nullptr) {
                FailPRspMsgFmt(resp,"Unknown port : %s", port.c_str());
                return true;
            }
            if(!p->handleCommandorCommand(cmd, req, resp))
                FailPRspMsgFmt(resp, "Fail handle device command : %s", cmd.c_str());
            return true;
        }

        void preparePattern() override {
            prepareSelfBind;
            bindHandler(controlSerial);
            bindHandler(controlPort);
            bindHandler(controlDevice);
            bindHandler(controlDebugger);
        }
    };
}
#endif //IOT_EDGE_VDALNEW_JEVDALCOMMONSERVICE_H
