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

#ifndef IOT_EDGE_VDALNEW_SERIALUTIL_H
#define IOT_EDGE_VDALNEW_SERIALUTIL_H

#include "JAExObjectV.h"

namespace jedge {

    class JE_API SerialUtil {
    public:
        static void loadInnerClasses(QJAMgServer &server) {
            auto clsStack = server.findClass("stack");
            //创建一个serial客户端
            //格式启动一个 //serial testIntf
            //openSerial serialName BLE_QJ [objName] --rate 115200
            clsStack->Method("openSerial", [&server]JAMethodConst(s,o,qm,sp) {
                PREPARE_PARAM(param, sp);
                auto serialPort = param.getParam(0);
                if(serialPort.empty()) {
                    QWarn("emtpy serial port.");
                    return false;   //stop running else code.
                }
                auto JedpRule = param.getParam(1);
                auto JedpObj = s.findContextObject(JedpRule);
                auto trans = std::dynamic_pointer_cast<qlibc::QByteTransfer>(JedpObj);
                if(JedpRule.empty() || trans==nullptr) {
                    QWarn("No valid jedp rule set.");
                    return false;
                }
                auto obj_name = param.getParam(2, "serialObj");

                //创建一个serial接口操作对象
                auto* data = server.getBlankMessage();
                param.setName(obj_name);
                param.setString("class", sval_cls_name_serial_port);
                param.setString("port", serialPort);
                data->copyDataNotStartWith(param, "@");
                s.getContext().clearObjectRef(obj_name);
                auto* port = new JASerialPort(s.getContext(), *data);
                port->setByteTransfer(trans);
                if(!port->open(s, param, nullptr)) {
                    delete port;
                    QWarn("Fail to open serial port %s", serialPort.c_str());
                    return false;
                }
                s.getContext().Object(obj_name, port);
                QLog("create a serial client %s ok", obj_name.c_str());
                //创建一个默认对象
                server.releaseMessage(data);
                return true;
            });

            auto seiral_port_cls = server.Class(sval_cls_name_serial_port, "object", false);
            bindJAClassCreator(seiral_port_cls, JASerialPort);

            // serialObj.open ttyUSB0 --rate 115200 --jedp BLE_QJ
            // serialObj.close
            // serialObj.writeHex '01 FF 33 03'
            // serialObj.writeMsg ${myMessage}
            // serialObj.handler /uri 'handler code'
            // serialObj.handler /uri 'handler code'
            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, seiral_port_cls, JASerialPort, open);
            JAUDS_DEFINE_CLASS_METHOD(server, seiral_port_cls, JASerialPort, close);
            JAUDS_DEFINE_CLASS_METHOD(server, seiral_port_cls, JASerialPort, writeHex);
            JAUDS_DEFINE_CLASS_METHOD(server, seiral_port_cls, JASerialPort, setFlowControl);
            JAUDS_DEFINE_CLASS_METHOD(server, seiral_port_cls, JASerialPort, setMsgHandle);
            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, seiral_port_cls, JASerialPort, setEncoderJedp);
            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, seiral_port_cls, JASerialPort, setJedp);
            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, seiral_port_cls, JASerialPort, writeMsg);
            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, seiral_port_cls, JASerialPort, handler);
            // ${@serialObj.isOpen} 函数返回值
            JAUDS_DEFINE_CLASS_FUNCTION(server, seiral_port_cls, JASerialPort, isOpen);
        }

        static void releaseClasses(QJAMgServer &server) {
            server.releaseClass(sval_cls_name_serial_port);
            server.removeClassMethod("stack", "openSerial");
        }
    };


}

#endif //IOT_EDGE_VDALNEW_SERIALUTIL_H
