from contextlib import contextmanager

from parallels.common.connections.target_servers import TargetServer
from parallels.common.utils import plesk_utils
from parallels.common.utils import windows_utils
from parallels.common.panel.server.plesk_family import HostingServer
from parallels.common.utils.session_dir import WindowsSessionDir
from parallels.common.utils.session_dir import UnixSessionDir
from parallels.common.utils import plesk_api_utils
from parallels.utils import cached

class PleskTargetServer(TargetServer):

	def __init__(self, conn):
		self.conn = conn
		if self.conn.is_windows:
			self._session_dir = WindowsSessionDir(
				self.runner, self.conn.windows_session_dir
			)
		else:
			self._session_dir = UnixSessionDir(
				self.runner, self.conn.unix_session_dir
			)

	@contextmanager
	def runner(self):
		with self.conn.main_node_runner() as runner:
			yield runner

	def get_hosting_server(self):
		return HostingServer(self)
		   
	def get_session_file_path(self, filename):
		return self._session_dir.get_file_path(filename)

	def session_dir(self):
		return self._session_dir.get_session_dir_path()

	def is_windows(self):
		return self.conn.is_windows

	def description(self):
		return 'target Plesk server'

	def ip(self):
		return self.conn.main_node_ip

	def ips(self):
		return set([self.ip()])

	def __hash__(self):
		return hash('1')

	def __eq__(self, another): 
		return isinstance(another, PleskTargetServer)

	def get_plesk_version(self):
		"""Return a tuple with Plesk server version."""
		with self.runner() as runner:
			return plesk_utils.get_plesk_version(runner)

	@property
	@cached
	def plesk_version(self):
		"""Return a tuple with Plesk server version."""
		version = plesk_api_utils.get_plesk_version(
			self.conn.plesk_api()
		)
		return tuple(map(int, (version.split("."))))

	@property
	@cached
	def vhosts_dir(self):
		if self.is_windows():
			get_vhosts_dir_function = plesk_utils.get_windows_vhosts_dir
		else:
			get_vhosts_dir_function = plesk_utils.get_unix_vhosts_dir

		with self.runner() as runner:
			return get_vhosts_dir_function(runner)

	@property
	@cached
	def plesk_dir(self):
		if self.is_windows():
			with self.runner() as runner:
				return windows_utils.detect_plesk_dir(runner.sh)
		else:
			raise NotImplementedError()
