
/*
 * Publisher API 
 */

#ifndef _INCLUDED_publish
#define _INCLUDED_publish

#ifdef _WIN32
#define __export __declspec(dllexport)
#else /* #ifdef _WIN32 */
#define __export
#endif /* #ifdef _WIN32 */

#ifdef __cplusplus
extern "C" {
#endif

#include "pasdisp.h"

#define PUBLISHER_ETIME -1

/** 
 * publisher_t : publisher
 * 
 * Really the only thing a publisher can to is publish, in other
 * words, submit notifications to the notification service.
 */
typedef struct publisher_struct publisher_t;

struct subscriber_struct;

/**
 * generic callback function
 *
 * callback functions of this type are invoked by the 
 * library to acknoledge an asynchronous call.
 *
 * Arguments:
 *
 *	arg	Context variable passed by the caller
 *
 *	rc	Return code
 *
 *	data	contains a newly created context in the
 *		case of an open.
 */
typedef void (*publisher_cb_t)(void *arg, int rc, void *data);


/**
 * creates a new publisher, asynchronously
 *
 * @param	disp	P&S thread pool context returned by 
 *			pas_dispatcher_new
 *
 * @param	worker	application worker.  If not NULL, it is grouped
 *			with the worker(s) created by ENS to service this 
 *			publisher session.  This is useful in order to 
 *			prevent 2 threads from accessing the publisher
 *			data at the same time.
 *
 * @param	host	notification server host name
 *
 * @param	port	notification server port
 *
 * @param	cbdone	callback invoked when the publisher has been
 *			successfully created or could not be created.
 *			If the creation is successful, the publisher
 *			is passed as the third argument (data) of cbdone.
 *			The second argument of cbdone is a status code
 *			If non-zero, it indicated that the publisher could
 *			not be created and specifies the cause of the 
 *			failure.
 *
 * @param	cbarg	First argument of cbdone.
 *
 * @return	new active publisher
 */
__export void publisher_new_a(pas_dispatcher_t *disp,
			      void *worker,
			      const char *host,
			      unsigned short port,
			      publisher_cb_t cbdone,
			      void *cbarg);
#define publisher_new publisher_new_a

/**
 * creates a new publisher
 *
 * @param	disp	thread dispatcher context, returned by 
 *			pas_dispatcher_new
 * @see	pas_dispatcher_new
 *
 * @param	worker	application worker.  If not NULL, it is grouped
 *			with the worker(s) created by ENS to service this 
 *			publisher session.  This is useful in order to 
 *			prevent 2 threads from accessing the publisher
 *			data at the same time.
 *
 * @param	host	notification server host name
 *
 * @param	port	notification server port
 *
 * @return	new active publisher
 */
__export publisher_t *publisher_new_s(pas_dispatcher_t *disp,
				      void *worker,
				      const char *host,
				      unsigned short port);


/**
 * sends an asynchronous notification to the notification service
 *
 * @param	publisher	publisher
 *
 * @param	event_ref	event reference.  This is a URI idendifying
 *				the resource that is modified.
 *
 * @param	data		event data.  The body of the notification
 *				message.  It must be a MIME object.  It 
 *				is opaque to the notification service and
 *				merely relayed by it.
 *
 * @param	datalen		length in bytes of the above data.
 *
 * @param	cbdone		callback invoked when the data has been
 *				accepted or deemed unacceptable by the 
 *				notification service.  Note that what makes 
 *				a notification accepted by the notification
 *				service depends on the protocol used.  The
 *				the protocol used may choose to use the
 *				transport ack (TCP) or have its own 
 *				acknowledgment response mechanism
 *
 * @param	end2end_ack	callback function invoked after acknowledgment
 *				from the peer (consumer) has been
 *				received.  This is used only in the context
 *				of a RENL.
 *
 * @param	cbarg		first argument of cbdone or end2end_ack when
 *				invoked.
 * @param       timeout         timeout to set to wait for RENL
 *
 */
__export void publish_a(publisher_t *publisher,
			const char *event_ref,
			const char *data,
			unsigned int datalen,
			publisher_cb_t cbdone,
			publisher_cb_t end2end_ack,
			void *cbarg,
			unsigned long timeout);
#define publish publish_a

/**
 * sends a synchronous notification to the notification service.  The 
 * call returns the notification has been successfully accepted or 
 * deemed unacceptable by the notification service.  In the context of 
 * a RENL, this call returns when the consumer has completely processed
 * the notification and successfully acknowledged it.
 *
 * @param	publisher	the publisher
 *
 * @param	event_ref	event reference.  This is a URI idendifying
 *				the resource that is modified.
 *
 * @param	data		event data.  The body of the notification
 *				message.  It must be a MIME object.  It 
 *				is opaque to the notification service and
 *				merely relayed by it.
 *
 * @param	datalen		length in bytes of the above data.
 *
 * @return	status code.    0 if success, failure code otherwise.
 */
__export int publish_s(publisher_t *publisher, 
		       const char *event_ref, 
		       const char *data,
		       unsigned int datalen);


/**
 * terminates a publish session
 *
 * @param	publisher	the publisher to terminate.
 */
__export void publisher_delete(publisher_t *publisher);



/**
 * creates a subscriber using the credentials of the publisher.
 * The goal is to simplify the creation of a publisher/subscriber
 * client, and to conserve resources in cases where publish and
 * subscribe services are closely tied.  It is really only useful 
 * when publish and subscriber services are closely tied. 
 * In other cases 
 * 
 * The returned subscriber is only valid as long as the subscriber is valid,
 * that is until publisher_delete has been called.
 *
 * @param	publisher	the publisher 
 *
 * @return	the subscriber, or NULL if trhe creation failed, in which
 *		case the subscriber API (subscriber_new) may have to be used.
 */
__export struct subscriber_struct *publisher_get_subscriber(publisher_t *publisher);



/**
 * RENL : Reliable Event Notification Link
 * 
 * A RENL is composed of a publisher and a subscriber and a RENL id
 * identifying notifications from the publisher received by the
 * subscriber that are subject to acknowledgment.  The fact that
 * the publisher has received the acknowledgment for a previously
 * sent notification is communicated to the application by invoking
 * the end2end_ack callback passed to the publish_a function.
 */
#ifndef _RENL_DEFINED_
#define _RENL_DEFINED_ 1
typedef struct renl_struct renl_t;
#endif /* _RENL_DEFINED_ */


/**
 * declares a RENL.  This function enables the end2end_ack invocation.
 * After this call returns, the end2end_ack argument passed to publish
 * is invoked any time an acknowledgment notification matching the
 * specified publisher and subscriber is subsequently received. 
 *
 * @param	publisher	the publisher
 *
 * @param	renl_id		unique RENL identifier.  this allows 2 peers
 *				to be able to set up multiple RENL's between
 *				the two of them.
 *
 * @param	subscriber	authenticated identity of the peer.
 *
 * @param	cbdone		callback invoked when the RENL is established
 *
 * @param	cbarg		first argument of cbdone when invoked.
 *
 */
__export void renl_create_publisher(publisher_t *publisher,
				    const char *renl_id, 
				    const char *subscriber,
				    publisher_cb_t cbdone,
				    void *cbarg);
    
/**
 * cancels and destroys a RENL.  
 * This does not prevent more notification to be sent.
 * It just means that the end2end_ack argument of publish will no longer
 * be invoked even if used, should a client acknowledgment be received.  
 *
 * All RENL's are automatically destroyed when the publisher is deleted.
 * Therefore, this function does not need to be called to freeup any RENL-
 * related memory before shuting down a publisher.
 *
 * @param	renl	the RENL to cancel
 *
 */
__export void renl_cancel_publisher(renl_t *renl);
    

#ifdef __cplusplus
}
#endif

#endif /* _INCLUDED_encapi */

