/*
 *  lib/grid.c
 *
 *  Grid APIs
 *
 *  Copyright (C) 2004  Phoenix Grid Computing Project
 *                      ( http://www.logos.ic.i.u-tokyo.ac.jp/phoenix/ )
 *
 *  2004-12-07  grid_select () and Grid_select () added 
 *              by Kaneda Kenji
 *  2004-11-26  Implemented basic functions 
 *              by Kenji Kaneda
 */


#include "common.h"
#include "debug.h"
#include "std.h"
#include "comm.h"


enum grid_error_kind {
	GRID_ERROR_KIND_SYS,
	GRID_ERROR_KIND_SSL
};
typedef enum grid_error_kind	grid_error_kind_t;


static struct comm_t *comm = NULL;


static bool_t
comm_is_initialized ( void )
{
	return ( comm != NULL );
}

static void
assert_init ( const char *func_name )
{
	assert ( func_name );
	
	if ( comm_is_initialized () )
		return;

	fatal_failure ( "grid_initialize() must be called before %s\n", func_name );
}

static void
assert_uninit ( void )
{
	if ( ! comm_is_initialized () )
		return;

	fatal_failure ( "grid_initialize() has already been called\n" );
}

void
grid_initialize ( const struct opt_t *opt )
{
	assert ( opt != NULL );
	assert_uninit ( );

	comm = Comm_new ( opt );
}

void
grid_finalize ( void )
{
	assert_init ( "grid_finalize()" );

	Comm_destroy ( comm );
}

int
grid_connect ( int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen )
{
	assert_init ( "grid_connect()" );

	return Comm_connect ( comm, sockfd, serv_addr, addrlen );
}

int
grid_bind ( int sockfd, struct sockaddr *my_addr, socklen_t addrlen )
{
	assert_init ( "grid_bind()" );

	return bind ( sockfd, my_addr, addrlen );
}

int
grid_listen ( int s, int backlog )
{
	assert_init ( "grid_listen()" );

	return listen ( s, backlog );
}

int
grid_accept ( int s, struct sockaddr *addr, socklen_t *addrlen )
{
	assert_init ( "grid_accept()" );
	
	return Comm_accept ( comm, s, addr, addrlen );
}

ssize_t
grid_send ( int s, const void *buf, size_t len, int flags )
{
	assert_init ( "grid_send()" );

	return Comm_send ( comm, s, buf, len, flags );
}

ssize_t
grid_recv ( int s, void *buf, size_t len, int flags )
{
	assert_init ( "grid_recv()" );

	return Comm_recv ( comm, s, buf, len, flags );
}

int
grid_shutdown ( int s, int how )
{
	assert_init ( "grid_shutdown()" );

	return Comm_shutdown ( comm, s, how );
}

int
grid_select ( int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
	      struct timeval *timeout )
{
	assert_init ( "grid_select()" );

	return Comm_select ( comm, n, readfds, writefds, exceptfds, timeout );
}


/* Return the error status of the last-called function. 
 * If the return value is GRID_ERROR_KIND_SYS, the error is caused by
 * system library. See errono to diagnose the error reason.
 * If the return value is GRID_ERROR_KIND_SSL, the error is caused by
 * SSL library. Use ERR_print_errors_fp () or other functions to
 * diagnose the error reason. */
grid_error_kind_t
grid_get_error_kind ( void )
{
	return GRID_ERROR_KIND_SYS;
}

/*******************************************************/

void
grid_failure ( char *string )
{
	ssl_failure ( string ); /* [???] */
}

void
Grid_connect( int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen )
{
	int ret;

	assert ( serv_addr != NULL );

	ret = grid_connect ( sockfd, serv_addr, addrlen );
	
	if ( ret == -1 )
		grid_failure ( "grid_connect" );
}

void
Grid_bind ( int sockfd, struct sockaddr *my_addr, socklen_t addrlen )
{
	int ret;
	
	assert ( my_addr != NULL );

	ret = grid_bind ( sockfd, my_addr, addrlen );
	
	if ( ret == -1 )
		grid_failure ( "grid_bind" );
}

void
Grid_listen ( int s, int backlog )
{
	int ret;
	
	ret = grid_listen ( s, backlog );
	
	if ( ret == -1 )
		grid_failure ( "grid_listen" );
}

int
Grid_accept( int s, struct sockaddr *addr , socklen_t *addrlen )
{
	int ret;

	ret = grid_accept ( s, addr, addrlen );
	
	if ( ret == -1 )
		grid_failure ( "grid_accept" );
		
	return ret;
}

size_t
Grid_send( int s, const void *buf, size_t len, int flags )
{
	ssize_t ret;

	ret = grid_send ( s, buf, len, flags );
	
	if ( ret == -1 )
		grid_failure ( "grid_send" );

	return (size_t) ret;
}

size_t
Grid_recv( int s, void *buf, size_t len, int flags )
{
	ssize_t ret;

	ret = grid_recv ( s, buf, len, flags );
	
	if ( ret == -1 )
		grid_failure ( "grid_recv" );

	return (size_t) ret;
}

int
Grid_select ( int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
	      struct timeval *timeout )
{
	int ret;

	ret = grid_select ( n, readfds, writefds, exceptfds, timeout );
	
	if ( ret == -1 )
		grid_failure ( "grid_select" );

	return (size_t) ret;	
}


