#pragma once
#include <signal.h>
#include <iostream>
#include "Util/logger.h"
#include "Network/TcpClient.h"
#include "Util/NoticeCenter.h"
#include "Notices.h"
#include <condition_variable>
#include <ctime>
#include <map>
#include <thread>

#include "Util/util.h"
#include "Util/logger.h"
#include "Network/Socket.h"
#include "Util/TimeTicker.h"
#include "Util/NoticeCenter.h"
#include "Poller/Timer.h"

#include <mutex>

using namespace std;
using namespace toolkit;

namespace gsd
{
    #define Request_timeout 4000
    #define Ok 200
    #define Internal_Server_Error 500
    #define Unauthorized 401
    #define Forbiddem 403
    #define Request_Time_out 408

    class TCPClient:public TcpClient
    {
    public:
        struct RequestAckTask
        {
            std::shared_ptr<Ticker> ticker = nullptr;
            std::string CommandEnum;
            function<void(int, std::string)> task; // 回调任务
            bool Finish = false;
        };

    public:
        typedef std::shared_ptr<TCPClient> Ptr;

        TCPClient():TcpClient() {
        }
        ~TCPClient() {}

        /**
         * @description: 发送请求
         * @param {string} RequestId  UUID
         * @param {string} CommandEnum 命令枚举
         * @param {string&} data  数据
         * @param {function<void(std::string)>} t 回调函数(请求结果, 返回的数据)
         * @return {*}
         */    
        void sendRequest(std::string RequestId,std::string CommandEnum, std::string& data,function<void(int, std::string)> t);

        /**
         * @description: 接收请求响应
         * @param {string&} json
         * @return {*}
         */    
        int requestAck(std::string& json);


    protected:
        /**
         * @description: 连接成功时触发
         * @param {SockException} &ex  连接info
         * @return {*}
         * @author: lishengyin
         */   
        virtual void onConnect(const SockException &ex) override;
        /**
         * @description: 接收数据时触发
         * @param {Ptr} &pBuf 接受到的数据
         * @return {*}
         * @author: lishengyin
         */    
        virtual void onRecv(const Buffer::Ptr &pBuf) override;
            /**
         * @description: 发送阻塞时触发
         * @param {*}
         * @return {*}
         * @author: lishengyin
         */  
        virtual void onFlush() override;
        /**
         * @description: EOF时触发
         * @param {SockException} &ex 错误信息
         * @return {*}
         * @author: lishengyin
         */   
        virtual void onErr(const SockException &ex) override;
            /**
         * @description: 心跳 2S触发一次
         * @param {*}
         * @return {*}
         * @author: lishengyin
         */ 
        virtual void onManager() override;

        /**
         * @description: 超时处理
         * @param {*}
         * @return {*}
         */    
        void requestOvertimeWork(std::string requestId, std::string CommandEnum);

    private:
        int _nTick = 0;
        std::string _IP;
        int32_t _port;

        Buffer::Ptr sbuf = nullptr;
        map<std::string, RequestAckTask> requestTasks;

        std::mutex m_mutex;
    };
} // namespace gsd