from contextlib import contextmanager
import ntpath

from parallels.utils import ip as ip_utils
from parallels.utils import cached
from parallels.common.connections.target_servers import DatabaseTargetServer
from parallels.common.utils import windows_utils

class PleskDatabaseTargetServer(DatabaseTargetServer):
	def __init__(
		self, conn, db_type, host, port, login, password, plesk_server
	):
		"""
		Arguments:
		- plesk_server - instance of PleskTargetServer
		"""
		self.conn = conn
		self.db_type = db_type
		self._host = host
		self._port = port
		self._login = login
		self._password = password
		self._plesk_server = plesk_server

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

	def is_windows(self):
		if self.is_external():
			raise Exception('Trying to get OS type for external database server. Getting OS type for external database server is not implemented.')
		return self.conn.is_windows

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

	@cached
	def ip(self):
		if self.host() == 'localhost':
			# pleskrestore restores 'localhost' databases to Plesk's main node
			# and Plesk's main node is PPA management node
			return self.conn.main_node_ip    
		else:
			# host may contain MS SQL instance name, e.g.
			# 10.50.52.100\MSSQLSERVER2008
			host = self.host().split('\\')[0]
			if host == '.':
				# the same as localhost
				return self.conn.main_node_ip
			else:
				return ip_utils.resolve(host) 

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

	def host(self):
		return self._host

	def port(self):
		return self._port

	def login(self):
		return self._login

	def password(self):
		return self._password

	def is_external(self):
		return self.ip() != self.conn.main_node_ip

	@cached
	def get_subscription_node(self):
		return self._plesk_server

	def get_session_file_path(self, filename):
		return self.get_subscription_node().get_session_file_path(filename)

	def session_dir(self):
		return self.get_subscription_node().session_dir()

	@property
	def mysql_bin(self):
		if not self.is_windows():
			raise NotImplementedError()

		with self.runner() as runner:
			plesk_dir = windows_utils.detect_plesk_dir(runner.sh)
		return ntpath.join(plesk_dir, "MySQL\\bin\\mysql")

	def __hash__(self):
		return hash((self.host(), self.port()))

	def __eq__(self, another): 
		return isinstance(another, PleskDatabaseTargetServer) and another.host() == self.host() and another.port() == self.port()
