#include "xsock.h"

#define VERBOSE 0
#define VERBOSETCP 0

using namespace std;
using namespace XSockExcept;

namespace XSock {

	void XSock::close_tcp(){
		::close(this->_sockFd);
	}

	void XSock::launch_tcp_client(){

		if((this->_sockFd=socket(AF_INET, SOCK_STREAM,0))==-1){
			perror("socket");
			throw eInvalidSocket();
		}
		if (connect(this->_sockFd,
					(struct sockaddr *)&this->_server,
					this->_server_length) < 0) { 
			::close(this->_sockFd); 
			perror("connect");
			throw eUnableToConnect();
		} 
	}

	void XSock::launch_tcp_server(){
		if((this->_sockFd=socket(AF_INET, SOCK_STREAM,0))==-1){
			throw eInvalidSocket();
		}

		if (bind(this->_sockFd,
					(struct sockaddr*)&this->_server,
					sizeof(this->_server))==-1)
		{
			throw eUnableToBind();
		}
		/*
		FD_ZERO(&this->_openSockFdSet);
		FD_SET(this->_sockFd, &this->_openSockFdSet);
		*/
		if (listen(this->_sockFd,this->_backlog)==-1){
			throw eUnableToListen();
		}
	} 


	XSock XSock::accept_tcp(){
		
		XSock *nXSock = new XSock(CLIENT,this->_proto);
		
		if((nXSock->_sockFd = ::accept(this->_sockFd,
									   (struct sockaddr *) &nXSock->_client,
									   &nXSock->_client_length)) == -1){
			if(VERBOSETCP>=1){perror("accept");}
			throw eUnableToAccept();
		}

		return *nXSock;
	}
	
	ssize_t XSock::recv_tcp(void *bufferData, ssize_t size){
		//TODO: commenter
		ssize_t p = read(this->_sockFd,bufferData,size);
		if(p == -1)
			throw XSockExcept::eSockUnreadable();
		return p;
	}

	ssize_t XSock::send_tcp(const void *bufferData, ssize_t size){
		//TODO : commenter
		ssize_t p = write(this->_sockFd,bufferData,size);
		if(p == -1)
			throw XSockExcept::eSockUnwritable();
		return p;
	}

	string XSock::get_client_ip(){
		return string(inet_ntoa(this->_client.sin_addr));
	}
	
	string XSock::get_client_dns(){
		//TODO: tout
		return string("");
	}
	
	string XSock::get_server_ip(){
		return string(inet_ntoa(this->_server.sin_addr));
	}

	string XSock::get_server_dns(){
		//TODO: tout
		return string("");
	}
	
}