
#ifndef _RTP808PROTOCOL_H_
#define _RTP808PROTOCOL_H_

#include "BaseService.h"
// #include "MediaWebSocketProtocol.h"
#include "Rtp808FrameParser.h"
#include "MediaClientConnection.h"

#if CONVERT_AAC
#include "codec/AllCodec.h"
#endif

namespace mfs
{
class Rtp808Protocol:public BaseProtocol
{
    public:

    private:
#if CONVERT_AAC
        std::shared_ptr<adpcm_state> _adpcmState;
        std::shared_ptr<Pcm2AAC> _pcm2aac;
        std::ofstream  testfilestreampcm;  
        std::ofstream  testfilestreamaac;  
#endif

        std::function<void(std::shared_ptr<Rtp808Protocol>)> _onConnectionFunc;
        std::function<void(std::shared_ptr<Rtp808Protocol>)> _onDisconnectionFunc;
        std::function<void(std::shared_ptr<Rtp808Protocol>)> _onReleaseFunc;
        std::function<int(char*, int)> _onDataCallback; 
        std::function<void(const std::string&)> _onDataErrorCallback; 
        std::shared_ptr<Rtp808FrameParser> _frameParser;                            // 解析rtp
        std::string _type;

        bool _isPlayback = false;                                                   // 是否回放

        bool _isTalk = false;                                                       // 是否是对讲
        uint64_t _timestamp = 0;                                                    // 当前RTP包时间戳(ms)

        bool _isYuebiao = false;                                                    // 是否粤标

        bool _isFirstFrame = true;
        std::string _uuid;                                                          // 当前uuid，房间标识
        
        int _logWriteFlag=0;
        int _logReadFlag=0;

        

        std::pair<std::vector<uint8_t>, int> _lastIFrame;
        std::pair<std::vector<uint8_t>, int> _frameBuffer[2];
        std::pair<std::vector<uint8_t>, int>* _currentBuffer;
        int _nextFramePos=0;                                                        // 下一帧要解析的rtp数据的位置
        bool _canParseNext = true;

        time_t _lastTime = 0;                                                       // epoll循环时间(s)

        // int check();
        // int parseRtpHead();                                                         // 解析已读数据的缓存，从中查找rtp头部
        int parseRtpBody();                                                         // 解析已读数据的缓存，从中查找rtp数据

        void updateTimestamp();


        int _flow = 0;
        int _allFlow = 0;
        std::string _startTime;
        std::string _endTime;

        static char magic[4];
        // static std::map<std::string, Rtp808Protocol*> clientMap;                            // 当前所有的RTP流
	public:
        Rtp808Protocol(std::shared_ptr<uvw::Loop> loop, std::shared_ptr<uvw::TCPHandle> client, const std::string& type);
        ~Rtp808Protocol();
        
        virtual void OnData(char* data, int dataLen) override;
        virtual void OnAlloc(uv_buf_t *buf, int suggested) override; 
        virtual void OnClose() override;
        virtual void OnReady() override;
        virtual int Write(char* data, int dataLen, bool forced = false) override;

        // 有效流开始时回调（有推，有订阅时）
        void OnFlowCallback();
        void OnRlease();

        // 
        void FlushAllData();

        void moveWebSocketList(std::shared_ptr<Rtp808Protocol> oldClient);                                  // 将旧的rtp连接对应的websocket移动到当前rtp连接

        const std::pair<std::vector<uint8_t>, int>& getIFrame(){return _lastIFrame;}
        
        const std::string& getUrl() const
        {
            return _frameParser->url();
        }

        const std::string& getUuid() const
        {
            return _uuid;
        }

        const std::string& getSimNumber() const
        {
            return _frameParser->simNumber();
        }

        bool isYuebiao(){return _isYuebiao;}
        void isYuebiao(bool v){_isYuebiao=v;_frameParser->isYuebiao(v);}

        int getChannel() const
        {
            return _frameParser->logicChannel();
        }

        int getCurrentFlow()
        {
            int flow = _flow;
            _flow = 0;
            return flow;
        }

        int addClient(std::shared_ptr<MediaClientConnection> client);

        const std::string& getType() const
        {
            return _type;
        }

        const std::string& getStartTime() const
        {
            return _startTime;
        }

        const std::string& getEndTime() const
        {
            return _endTime;
        }

        void updateStreamInfo(const std::string& vehicleId, const std::string& userID, const std::string& uuid);

        std::shared_ptr<MediaClientConnection> getRecordSocket();

        void SetOnConnection(std::function<void(std::shared_ptr<Rtp808Protocol>)> listen){_onConnectionFunc=listen;}
        void SetOnDisconnection(std::function<void(std::shared_ptr<Rtp808Protocol>)> listen){_onDisconnectionFunc=listen;}
        void SetOnDataCallback(std::function<int(char*, int)> listen){_onDataCallback=listen;}
        void SetOnReleaseCallback(std::function<void(std::shared_ptr<Rtp808Protocol> rtp)> listen){_onReleaseFunc=listen;}
        void SetOnDataErrorCallback(std::function<void(const std::string&)> listen){_onDataErrorCallback=listen;}

        
        virtual void alogd(const std::string& message, const std::string& fileName, const int line, const std::string& functionName)  override 
        {
            // printf("Rtp808Protocol alogd\n");
            BaseProtocol::alogd(std::string()+"["+getUrl()+"]"+message, fileName, line, functionName);
        }
        virtual void aloge(const std::string& message, const std::string& fileName, const int line, const std::string& functionName)  override 
        {
            BaseProtocol::aloge(std::string()+"["+getUrl()+"]"+message, fileName, line, functionName);
        }
        virtual void alogv(const std::string& message, const std::string& fileName, const int line, const std::string& functionName)  override 
        {
            BaseProtocol::alogv(std::string()+"["+getUrl()+"]"+message, fileName, line, functionName);
        }
};

}


#endif //_RTP808PROTOCOL_H_