#pragma once
#include "reactor.hpp"
#include <functional>
#include <mutex>
#include <sys/epoll.h>
#include <unordered_map>

namespace tinyrpc {

   
    enum class IOEvent{
        READ = EPOLLIN,
        WRITE = EPOLLOUT,
        // ERROR = EPOLLERR
    };
    

    class FdEvent {
        friend class FdEventPool;
    public:
        void clearListenEvent() {
            m_listen_events = 0;
        }
        int getFd() const{return m_fd;}
        int getEvent() const { return m_listen_events;}
        void setReadCallback(std::function<void()> read_callback) {
            m_read_callback = read_callback;
        }
        void setWriteCallback(std::function<void()> write_callback) {
            m_write_callback = write_callback;
        }

        bool setNonblock();
        std::function<void()> getHandler(IOEvent event) const;
        void addListenEvent(IOEvent event);
        void delListenEvent(IOEvent event);
        void reset();
    protected:
        FdEvent(int fd);
        ~FdEvent();
        FdEvent() = default;
        FdEvent(int fd, Reactor* reactor);
        FdEvent(const FdEvent&) = delete;
    protected:

        int m_fd {-1};
        Reactor::Task   m_read_callback{m_default_callback};
        Reactor::Task  m_write_callback{m_default_callback};
        // std::function<void()> m_error_callback{nullptr};
        Reactor* m_reactor{nullptr};  // 这个fd 所属的 reactor
        int m_listen_events {0};  // 这个fd 关心的事件

        static Reactor::Task m_default_callback;
    };


    class FdEventPool{
    public:
        static FdEventPool* getInstance();
        FdEvent* getFdEvent(int fd);
        ~FdEventPool();
    private:
        FdEventPool() = default;

    private:
        std::mutex m_mtx{};
        std::unordered_map<int, FdEvent*> m_fdEvents{};

    };


}