/*! 
 * \file XSock.hpp blabla  
 *
 */ 

#ifndef _XIONFS_XSOCK
#define _XIONFS_XSOCK 1

#include "xsock_errors.h"
#include "xsock_global.h"
#include "xsock_iface.h"

using namespace std;
using namespace XSockExcept;

namespace XSock {
	/*
	 * XSock permet de gérer une connexion TCP ou UDP.
	 */	

	class XSock {
		private:
			protocol _proto;
			xsock_role _role;

			/* descripteur de la socket principale */
			int _sockFd;

			/* taille de la table des descripteurs */
			int _sockSetDSize;

			/* ensemble de sockets ouverts */
			fd_set _openSockFdSet;
			
			/* ensemble de sockets ouverts qui attendent d'être lus */
			fd_set _openSockFdSet_R;

			/* fixer la taille de la queue d'attente de connexions*/
			int _backlog;
			
			
			/* membres à ajouter pour les service par dessus udp */
			// numéros de séquence entrante
			u_int _secnumrecv;
			// numéros de séquence sortante
			u_int _secnumsend;
			
			/* structure d'addresse du client */
			struct sockaddr_in _client;
			socklen_t _client_length;

			/* structure d'addresse du serveur */
			struct sockaddr_in _server;
			socklen_t _server_length;
		
			void launch_tcp_client();
			void launch_udp_client();
			void launch_udp_reliable_client();
			void launch_tcp_server();
			void launch_udp_server();
			void launch_udp_reliable_server();

			XSock accept_udp();
			XSock accept_udp_reliable();
			XSock accept_tcp();
			int sockFdTab_newPlace();
			int sockFdTab_getPlace(int);
                        
			unsigned short XSock::getAvailablePortPub();
                        
			void backlog(int );
			
			ssize_t send_udp(const void *, ssize_t );
			ssize_t send_udp_reliable(const void *, ssize_t );
			ssize_t send_tcp(const void *, ssize_t );
			ssize_t recv_udp(void *, ssize_t );
			ssize_t recv_udp_reliable(void *, ssize_t );
			ssize_t recv_tcp(void *, ssize_t );
	
			void close_tcp();
			void close_udp();
			void close_udp_reliable();
		public:
			XSock(xsock_role, protocol);

			void port(u_short ); // client
			void ip(int );
			void dns(string );

			XSock accept();
			void launch();
			void close();
			ssize_t send(const void *, ssize_t );
			ssize_t recv(void *, ssize_t );

			char * getClientAddress();
			char * getServerAddress();

			u_short get_local_port();
			u_short get_server_port();
			string get_server_dns();
			string get_server_ip();
			string get_client_dns();
			string get_client_ip();
			void dump_info();
	}; // end class

} // end namespace

#endif