#!/usr/bin/env python

# This file is part of Window-Switch.
# Copyright (c) 2009-2013 Antoine Martin <antoine@nagafix.co.uk>
# Window-Switch is released under the terms of the GNU GPL v3

from winswitch.consts import LOCALHOST
from winswitch.util.simple_logger import Logger
from winswitch.client.server_line_connection import ServerLineConnection
from winswitch.objects.server_config import ServerConfig

from winswitch.server.client_channel import WinSwitchClientChannel



class EmbeddedClientChannelTransport:
	"""
		Define some fake methods to comply with the transport interface as used by client channel.
		This is used by the server end.
	"""

	def __init__ (self):
		Logger(self)

	def getPeer(self):
		class peer:
			self.host = LOCALHOST
			self.port = 0
		return peer()

	def loseConnection(self):
		self.slog()

class EmbeddedClientChannelFactory:
	"""
		Fake factory for direct channel when the server is embedded.
		This is used by the server end.
	"""

	def __init__ (self, controller, writeback_method):
		Logger(self)
		self.sdebug(None, controller, writeback_method)
		self.controller = controller
		self.writeback_method = writeback_method
		self.local = True
		self.numProtocols = 0
		self.channel = None

	def __str__(self):
		return	"EmbeddedClientChannelFactory(%s,%s)" % (self.controller, self.local)

	def write(self, msg):
		self.channel.lineReceived(msg)

	def buildProtocol(self):
		""" Constructs a client channel, the address is ignored """
		self.channel = WinSwitchClientChannel()
		self.channel.transport = EmbeddedClientChannelTransport()
		self.channel.factory = self
		self.channel.write = self.writeback_method
		return	self.channel



class EmbeddedServerChannelFactory:
	"""
		Fake factory for direct channel when the server is embedded.
		This is used by the client end.
	"""

	def __init__ (self, server_link):
		Logger(self)
		self.slog(None, server_link)
		self.server_link = server_link
		self.abort = False
		self.do_retry = False
		self.closed = True
		self.server_channel = None

	def is_connected(self):
		return	True

	def connect(self):
		""" Connects a fake client with a fake server endpoint """
		""" Hook up a ServerLineConnection to our local methods for sending and receiving """
		client = ServerLineConnection(self.server_link, self.write, self.stop, self.is_connected)
		self.server_link.set_client(client)
		def add_all(*args):
			client.add_default_handlers()
			client.add_trusted_handlers()
		client.add_handlers = add_all
		""" Hook up the EmbeddedClientChannelFactory to our ServerLineConnection """
		f = EmbeddedClientChannelFactory(self.server_link.server.embedded_server, client.lineReceived)
		self.server_channel = f.buildProtocol()
		""" Now we're ready - go! """
		self.server_link.set_server_status(self, ServerConfig.STATUS_CONNECTED)
		self.server_channel.connectionMade()
		client.connectionMade()

	def stop(self, *args, **kwargs):
		self.slog("not implemented!", args, str(kwargs))

	def write(self, data):
		""" This is called by ServerLineConnection to send data to the server channel """
		self.server_channel.lineReceived(data)
