#pragma once
#include "AftrConfig.h"
#include <memory>
#include <string>
#ifdef AFTR_CONFIG_USE_BOOST
#include <boost/log/detail/asio_fwd.hpp>
//#include <boost/asio.hpp>
//#include <boost/thread.hpp>
//forward declare boost classes
namespace boost
{
   class thread;
   namespace asio
   {
      class io_context;
   }
}

namespace Aftr
{

class NetMessengerServerListener;
class NetMessengerServerSession;




class NetMessengerServer
{
public:
   static std::unique_ptr< NetMessengerServer > New();

   //After the Engine has initialized, sometimes a user wants a TCP session between itself and another endpoing. This
   //factory method is the *simplest* way to create a TCP session that hooks in to the asynchronous IO (really fast) 
   //for sending and receiving NetMsgs... Internally, this wraps up the details of creating a NetMessengerServerSession
   //and connects the io_context and internal message queues with the singler NetMessengerServer already running.
   //If the GLView hasn't yet initialized or created the main NetMessengerServer, this method will return nullptr.
   //If a TCP connection to host:port is not able to be established, this method will return nullptr.
   //This method is identical / does the exact same thing as NetMessengerServerSession::createNew_TCP_Session.
   //After creating a TCP Session, the user can connect by calling session->connectSessionToHost( ip, port );
   static std::shared_ptr< NetMessengerServerSession > createNew_TCP_Session();

   ~NetMessengerServer();
   void onUpdate();
   NetMessengerServerListener& getServerListener();
   boost::asio::io_context const& getIOContext() const;
   boost::asio::io_context&       getIOContext();
private:
   NetMessengerServer() = default;
   NetMessengerServer( NetMessengerServer const& ) = delete;
   NetMessengerServer( NetMessengerServer&& ) = delete;
   NetMessengerServer& operator=( NetMessengerServer const& ) = delete;
   NetMessengerServer& operator=( NetMessengerServer&& ) = delete;

   void onCreate();
   void onUpdateRecvData();
   void onUpdateSendData();

   std::unique_ptr< boost::asio::io_context > ioContext; ///< Boost's cross platform interface with OS networking
   std::unique_ptr< NetMessengerServerListener > serv; ///< Message Server which listens on IP:PORT (ipv4 or ipv6)
   std::unique_ptr< boost::thread > ioContextThread; ///< Thread which handles async io
};


} //namespace Aftr

#endif //AFTR_CONFIG_USE_BOOST
