#pragma once
#include "abstract_coder.hpp"
#include "abstract_dispatcher.hpp"
#include "coroutine.hpp"
#include "io_thread.hpp"
#include "net_address.hpp"
#include "protocol_type.hpp"
#include <cstdint>
#include <google/protobuf/service.h>
// #include "reactor.hpp"

namespace tinyrpc {
    class TcpAcceptor{
    public:
        TcpAcceptor(const NetAddress& netAddr);
        void init();
        int accept();
    private:
        int m_listenfd{-1};
        NetAddress m_bindNetAddr;
    };

    class TcpServer{

    public:
        TcpServer();
        TcpServer(const NetAddress& addr);
        TcpServer(const std::string& ip, uint16_t port);
        ~TcpServer();
        void start();
        AbstractCoder& getCoder() {return *m_coder;}
        AbstractDispatcher& getDispatcher() {return *m_dispatcher;}
        void registerService(std::shared_ptr<google::protobuf::Service> service);
    private:
        void mainAcceptCorFun();
    private:

        // Reactor* m_reactor{nullptr};
        Coroutine m_accept_cor;
        TcpAcceptor m_acceptor;
        bool m_stop_accept{false};
        // int m_conn_cnt{0};
        // IOThread m_ioThread{};
        IOThreadPool m_ioThreadPool{4};
        AbstractCoder* m_coder{};
        AbstractDispatcher* m_dispatcher{};
        ProtocolType m_protocolType{ProtocolType::Tinypb};
    };

}