require 'rex/socket'

module Rex
module Socket

###
#
# This mixin provides the basic interface that a derived class must implement
# in order to be a compatible comm class.  The base comm class also supports
# registering event handlers that can be notified when sockets are being
# created and have been created.  This allows code to extend sockets on
# creation from the single point that they are created.
#
###
module Comm

	###
	# 
	# This mixin provides stubs for event notification handlers that can be
	# registered with a Comm factory to be called when various events occur,
	# such as socket instantiation.
	#
	###
	module Events

		#
		# This callback is notified when a socket is being created and is passed
		# the parameters that will be used to create it.
		#
		def on_before_socket_create(comm, param)
		end

		#
		# This callback is notified when a new socket is created and the
		# parameters that were used to create it.  This provides the callback
		# with a chance to extend or otherwise modify the socket before it's
		# passed on to the actual requestor.
		#
		def on_socket_created(comm, sock, param)
		end

	end

	#
	# Creates a compatible socket based on the supplied uniform parameters.
	#
	def self.create(param)
		raise NotImplementedError
	end

	#
	# Indicates whether or not this comm can be chained with other chainable
	# comms.  This is particularly important for things like Proxy Comms that
	# can be proxied through one another.  The semantics of this are currently
	# undefined and will probably need some more thought.
	#
	def chainable?
		false
	end

	#
	# Registers an event handler that implements the Rex::Socket::Comm::Event
	# interface in at least some fashion.  Event handlers are notified when
	# sockets are created through the Comm instance that they register against.
	#
	def register_event_handler(handler)
		if (handlers == nil)
			self.handlers        = []
		end

		self.handlers << handler
	end

	#
	# Deregisters a previously registered event handler.
	#
	def deregister_event_handler(handler)
		if (handlers)
			handlers.delete(handler)
		end
	end

	#
	# Enumerates each registered event handler so that they can be notified of
	# an event.
	#
	def each_event_handler(&block)
		if (handlers)
			handlers.each(&block)
		end
	end

	#
	# Notifies handlers of the before socket create event.
	#
	def notify_before_socket_create(comm, param)
		each_event_handler() { |handler|
			handler.on_before_socket_create(comm, param)
		}
	end

	#
	# Notifies handlers of the socket created event.
	#
	def notify_socket_created(comm, sock, param)
		each_event_handler() { |handler|
			handler.on_socket_created(comm, sock, param)
		}
	end

protected

	attr_accessor :handlers # :nodoc:
	attr_accessor :handlers_rwlock # :nodoc:

end

end
end
