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

#ifndef LIBDEVCPP_SOCKETBUFFER_H
#define LIBDEVCPP_SOCKETBUFFER_H

#include <string>
#include <qlibc/qlibc.h>

#include "MgBusCommon.h"

namespace jedge {

        static const char default_devicer_char_[] = {JSON_RPC_MESSAGE_DEVIDER_CHAR,JSON_RPC_MESSAGE_DEVIDER_CHAR_R,'\0'};

        class JE_API DataDivider {
            protected:
            const char* divider_chars_;
            public:
            explicit DataDivider(const char* deviderChars = default_devicer_char_) :
            divider_chars_(deviderChars){}

            inline bool isDividerChar(char ch) const {
                if(divider_chars_== nullptr)
                    return ch==0;
                for(int i=0;divider_chars_[i];i++)
                    if(divider_chars_[i]==ch) return true;
                return false;
            }
        };

        using BufferChecker = std::function<bool(const char* buff, std::string& str)>;

        class JE_API SocketBuffer {
            public:
            char* buff_;
            unsigned long buff_size_;
            int  buffferd_len_ = 0;
            BufferChecker* buffer_checker_ = nullptr;

            explicit SocketBuffer(unsigned long  bufferSize = MGBUS_CLIENT_DATA_BUFFER_SIZE) {
                buff_size_ = bufferSize;
                buff_ = new char[bufferSize+1];
            }

            ~SocketBuffer() {
                delete[] buff_;
                delete buffer_checker_;
            }

            int makeJsonMessage(const DataDivider& devider, int start, const char *buff, int len, string& message);

            void setBufferChecker(const BufferChecker& checker){
                if(buffer_checker_==nullptr) buffer_checker_ = new BufferChecker(checker);
                else *buffer_checker_ = checker;
            }
        };

        //
        class JE_API JsonSocketBuff : public SocketBuffer {
            explicit JsonSocketBuff(unsigned long  bufferSize = MGBUS_CLIENT_DATA_BUFFER_SIZE) : SocketBuffer(bufferSize) {
                buffer_checker_ = new BufferChecker([](const char *buff, std::string& target)->bool{
                    target = buff;
                    Json::Value v;
                    return StringUtils::parseJson(target, v);
                });
            }
        };

};
#endif //LIBDEVCPP_SOCKETBUFFER_H
