//
// Created by Ht on 2021/1/9.
//

#ifndef LIBDEVCPP_SERIALPORT_H
#define LIBDEVCPP_SERIALPORT_H

#include <string>
#include <vector>
#include <jebase/config.h>
#include <qlibc/StringUtils.hpp>
#include <qlibc/ByteUtils.h>
#include <thread>
#include <functional>

namespace jedge {

    const static uint16_t ival_comm_buff_size = 1024;
    const static uint16_t ival_comm_buff_max = 32768;

    class JE_API SerialIOHolderInterface {
    public:
        virtual ~SerialIOHolderInterface() = default;
        virtual void onSerialDataRead(const std::string& portName, QByte *data, uint16_t len) = 0;
        virtual void onSerialStart() = 0;
        virtual bool writeSerialRawData(QByte* buff, int32_t len) = 0;
    };

    using RSerialIOHolderInterface = std::shared_ptr<SerialIOHolderInterface>;

    class JE_API SerialPort {
    protected:
        std::vector<RSerialIOHolderInterface> mHolders;
        std::string name_;
        std::thread* read_thread_ = nullptr;
        QByte  mSerialDataBuff[ival_comm_buff_size];
        uint16_t  mBuffLen;

        virtual void procSerialDataEvent() = 0;
        virtual void readSerialData() = 0;
        virtual void onSerialDataRead();


    public:
        virtual bool initSerialPort(unsigned int nBaud) = 0;
        virtual bool writeData(uint8_t *buff, int32_t len) = 0;
        virtual bool closeSerialPort() = 0;


    public:
        explicit SerialPort(const std::string &portName);
        virtual ~SerialPort();;
        void appendHolder(jedge::RSerialIOHolderInterface& holder);

        static bool comPortDetected(const std::string &comNum, const std::string &checkKeyWord); //检验串口号是否依然存在
        static void scanTargetPort(QStringList &comNameList, const std::string &comKeyWord);
        const std::string &getName();


        void start();
        void onSerialStart();
        void queryNetwork();
        void startReadSerialData();
    };

}

#endif //LIBDEVCPP_SERIALPORT_H
