#ifndef __TCPServerSocket_h__
#define __TCPServerSocket_h__

#include "Socket.h"
#include "TCPSocket.h"
#include "Service.h"

namespace core {
   
   ///
   /// TCPServerSocket
   ///
   /// Manage a socket connection as a TCP server type. Connections to the socket are processed through
   /// the accept functionality. 
   ///
   /// A list of connections is maintained in a vector object. 
   ///
   /// This object extends the BMACommand object as well so it can be added to a Console object and
   /// process commands to display status information.
   ///
   
   class TCPServerSocket : public TCPSocket, public Command {
      
    public:
      
      ///
      /// The constructor for the BMATCPSocket object.
      ///
      /// @param ePoll the EPoll instance that manages the socket.
      /// @param url the IP address for the socket to receive connection requests.
      /// @param port the port number that the socket will listen on.
      /// @param commandName the name of the command used to invoke the status display for this object.
      /// @return the instance of the BMATCPServerSocket.
      
      TCPServerSocket(EPoll &ePoll, std::string url, short int port);
      
      ///
      /// The destructor for this object.
      ///
      
      ~TCPServerSocket();
      
    protected:
      
      virtual void init();
      
      ///
      /// getSocketAccept is designed to allow a polymorphic extension of this object to
      /// return a type of object that extends the definition of the server socket.
      /// Returning the appropriate session object that extends from BMASession provides
      /// the mechanism where the server can select the protocol dialog for the desired 
      /// service.
      /// 
      
      virtual Session * getSocketAccept();

      /// 
      /// TCP servers can have an associated Service object that provides services for
      /// sessions created by the server. You can extend the Service object and place 
      /// commands and server application support for extended servers.
      ///
      
      virtual Service * getService();
      
      ///
      /// Override the virtual dataReceived since for the server these
      /// are requests to accept the new connection socket.
      /// No data is to be read or written when this method is called. It is the response to 
      /// the fact that a new connection is coming into the system 
      ///
      /// @param data the pointer to the buffer containing the received data.
      /// @param length the length of the associated data buffer.
      ///
      
      void onDataReceived(std::string data) override;      
      
      ///
      /// This method is called when the Command associated with this object is requested
      /// because a user has typed in the associated command name on a command entry line. 
      ///
      /// @param the session object to write the output to.
      ///
      
      int processCommand(std::string command, Session *session) override;

      Service *service;
		      
    private:

      Session * accept();
      Service * _getService();
      
   };
   
}

#endif
