// -*- c++ -*-
//------------------------------------------------------------------------------
//                             ServiceHandler.h
//------------------------------------------------------------------------------
//  Copyright (c) 1999 by Vladislav Grinchenko
//
//  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.
//
//------------------------------------------------------------------------------
//  Created: 06/07/99
//------------------------------------------------------------------------------
#ifndef SERVICE_HANDLER_H
#define SERVICE_HANDLER_H

#include "assa/Assert.h"
#include "assa/EventHandler.h"

namespace ASSA {

/** @file ServiceHandler.h

    This abstract class provides generic interface for processing services.
	Application must customize this class to perform a particular type
	of services.
*/

template <class PEER_STREAM>
class ServiceHandler : public EventHandler
{
public:
	/** Default constructor. 
	    In case of server-side, ServiceHandler is created by
	    Acceptor, when new connection is detected.
	 */
	ServiceHandler () 
		: m_peerStream (new PEER_STREAM)
		{
			trace("ServiceHandler::ServiceHandler");
		}
		
	/** Constructor that takes PEER_STREAM as a parameter. 
	    In case of server-side, ServiceHandler is created by
	    Acceptor, when new connection is detected. Note that PEER_STREAM
	    is created by PEER_STREAM::accept () method.
	 */
	ServiceHandler (PEER_STREAM* ps_)
		: m_peerStream (ps_) 
		{
			trace("ServiceHandler::ServiceHandler");
		}

	/// Destructor closes and deletes PEER_STREAM.
	virtual ~ServiceHandler () {
		trace("ServiceHandler::~ServiceHandler");

		if ( m_peerStream ) {
			delete m_peerStream;
			m_peerStream = (PEER_STREAM*) NULL;
		}
	}
	
	/** Pure virtual method defined by subclass. The open()
		hook is called by the Acceptor or Connector once a 
		connection is established. The behavior of this method
		must be defined by a subclass, which typically performs
		any service-specific initialization.
	*/
	virtual int open (void) = 0;

	/** Pure virtual method defined by subclass. The close()
		hook closes PEER_STREAM by default
		The behavior of this method can be changed by a subclass, 
		which typically performs any service-specific cleanup.
		EventHandler::handle_close() method of base class EventHandler
		is called when client closes connection. ServiceHandler
		object can destroy itself from there.
	*/
	virtual void close (void) 
		{
			trace("ServiceHandler::close");
			if ( m_peerStream ) m_peerStream->close ();
		}

	/** Conversion operator to type PEER_STREAM &.
	    Comes handy when you want to call underlying PEER_STREAM
	    member functions directly.

	    @return reference to underlying stream mechanism
	 */
	operator PEER_STREAM& () 
		{ 
			trace("ServiceHandler::opt PEER_STREAM& ()");
			return *m_peerStream;
		}

	/// Return referenct to underlying PEER_STREAM.
	PEER_STREAM& get_stream () { return *m_peerStream; }

protected:
	/** Concrete Socket instance. ServiceHandler owns this
	    object which is delete()-ed in destructor.
	 */
	PEER_STREAM* m_peerStream;
};

} // end namespace ASSA

#endif /* SERVICE_HANDLER_H */
