// -*- c++ -*-
//------------------------------------------------------------------------------
//                            EventHandler.h
//------------------------------------------------------------------------------
//  Copyright (C) 1997-2002  Vladislav Grinchenko <vladg@erols.com>
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//---------------------------------------------------------------------------
#ifndef _EventHandler_h
#define _EventHandler_h

#include "assa/Assert.h"

namespace ASSA {

/** @file EventHandler.h 

    An abstract interface for handling I/O events, timers, and such.
*/

/** @var unsigned long TimerId.
	Timer Id is used in handle_timeout() calls. 
*/
typedef unsigned long TimerId;

/** @enum EventType

EventType defines events types that Reactor understands.
*/

enum EventType
{	
	READ_EVENT    = 0x01,	/**< Notify when there will be at least 1 byte 
							   available for reading from IO channel without 
							   blocking .   */
	WRITE_EVENT   = 0x02,	/**< Notify when there will be room for at least 
							   1 byte to be written to IO channel without 
							   blocking.   */
	EXCEPT_EVENT  = 0x04,	/**< Notify when there is an exception condition
							 detected in TCP layer. */
	TIMEOUT_EVENT = 0x10,	/**< Notify about expired timer. */
	SIGNAL_EVENT  = 0x20,	/**< Notify when UNIX signal is delivered by OS */
	RWE_EVENTS    = 0x07,	/**< READ_EVENT | WRITE_EVENT | EXCEPT_EVENT   */
	ALL_EVENTS    = 0x37	/**< Mask that includes all events. */
};

inline 
bool isReadEvent (EventType e_) 
{     
	return (e_ & READ_EVENT) == READ_EVENT;
}

inline 
bool isWriteEvent (EventType e_) 
{
	return (e_ & WRITE_EVENT) == WRITE_EVENT;
}

inline 
bool isExceptEvent (EventType e_) 
{
	return (e_ & EXCEPT_EVENT) == EXCEPT_EVENT;
}

inline
bool isTimeoutEvent (EventType e_) 
{
	return (e_ & TIMEOUT_EVENT) == TIMEOUT_EVENT;
}

inline
bool isSignalEvent (EventType e_) 
{
	return (e_ & SIGNAL_EVENT) == SIGNAL_EVENT;
}

inline 
bool isRWEEvents (EventType e_) 
{
	return isReadEvent (e_) && isWriteEvent (e_) && isExceptEvent (e_);
}

inline 
bool isAllEvents (EventType e_) 
{
	return isReadEvent (e_) && isWriteEvent (e_) && isExceptEvent (e_) &&
		isSignalEvent (e_) && isTimeoutEvent (e_) ;
}

/** EventHandler class.

EventHandler is a pure virtual class. It is an interface class to the 
Event Handlers. These events are processed by Reactor. The supported events
are signals, timers, and I/O pipes such as file descriptors, sockets and such.

@see EventType
*/

class EventHandler
{
public:
	/// Constructor
	EventHandler();

	/** Read event callback. If reader detects EOF, it must
	    return error to the Reactor. (See Reactor for details).
	    @return 0 on success, -1 on error
	*/
	virtual int handle_read (int fd);

	/** Write handler callback. 
	    @return 0 on success, -1 on error
	*/
	virtual int handle_write (int fd);

	/** Exception handler callback.
	    @return 0 on success, -1 on error
	*/
	virtual int handle_except (int fd);

	/** Timeout handler callback.
		Return value is ignore. If you want repetetive timer event,
		you should reinstall an event handler before returning control
		to the calling function.
	    @return 0 on success, -1 on error
	*/
	virtual int handle_timeout (TimerId tid);

	/** Signal handler callback.
	    @return 0 on success, -1 on error
	*/
	virtual int handle_signal(int signum_); 

	/** EOF on peer socket handler callback. There is no
	    corresponding EventType. One is not needed because detecting
	    EOF is a part of handle_read () data processing.
	    @return 0 on success, -1 on error
	*/
	virtual int handle_close (int fd);

	/** A hook for derived class to reset internal state
	    as needed.
	*/
	virtual void resetState (void);
};

inline
EventHandler::
EventHandler()
//	: m_id(-1)
{
	trace_with_mask("EventHandler::EventHandler",REACTTRACE);
}

inline int 
EventHandler::
handle_read (int /* fd */)
{
	trace_with_mask("EventHandler::handle_read",REACTTRACE);
	return -1;
}

inline int 
EventHandler::
handle_write (int /* fd */)
{
	trace_with_mask("EventHandler::handle_write",REACTTRACE);
	return -1;
}

inline int 
EventHandler::
handle_except (int /* fd */)
{
	trace_with_mask("EventHandler::handle_except",REACTTRACE);
	return -1;
}

inline int 
EventHandler::
handle_timeout (TimerId /* timer_id */)
{
	trace_with_mask("EventHandler::handle_timeout",REACTTRACE);
	return -1;
}

inline int 
EventHandler::
handle_signal (int /* signum_ */) 
{
	trace_with_mask("EventHandler::handle_signal",REACTTRACE);
	return -1;
}

inline int 
EventHandler::
handle_close (int /* fd */)
{
	trace_with_mask("EventHandler::handle_close",REACTTRACE);
	return -1;
}

inline void 
EventHandler::
resetState (void) 
{
	trace_with_mask("EventHandler::reset",REACTTRACE);
}

/** @var int (EventHandler::*EH_IO_Callback) (int)

A type for the pointer to I/O-related callback member function 
of class EventHandler.
These are:
   - handle_read ()
   - handle_write ()
   - handle_except ()

@see EventHandler
*/
typedef int (EventHandler::*EH_IO_Callback) (int);

} // end namespace ASSA

#endif // _EventHandler_h
