from collections import namedtuple
from contextlib import contextmanager
import logging
import pymssql

from parallels.core.utils.common import cached
from parallels.core.connections.connections import Connections
from parallels.core.utils.common_constants import WINDOWS_SOURCE_DEFAULT_SESSION_DIR
from parallels.core.utils.config_utils import ConfigSection
from parallels.core.migrator_config import read_windows_auth
from parallels.core.migrator_config import read_copy_mail_content_settings
from parallels.core.migrator_config import read_windows_agent_settings
from parallels.core.utils.common.sql_utils import DatabaseWrapper
from parallels.ppa.source.helm4.server import HelmSourceServer

logger = logging.getLogger(__name__)
DbSettings = namedtuple('DbSettings', ('host', 'name', 'port', 'user', 'password'))


class HelmMigratorConnections(Connections):
	def __init__(self, global_context, target_panel, migrator_server):
		super(HelmMigratorConnections, self).__init__(global_context, target_panel)
		self.helm = HelmConnections(read_helm_settings(global_context.config, 'helm'), migrator_server)

	@cached
	def get_source_node(self, node_id):
		return self.helm.get_main_source_server()

	def get_information_servers(self):
		return {'helm': self.helm.conn_settings}

	def check_helm(self):
		# TODO: Add checks for helm connection
		pass


class HelmConfig(namedtuple('HelmConfig', (
		'id', 'ip',  'windows_auth', 'db',
		'migration_tool_dir', 'migration_tool_name', 'session_dir',
		'mail_settings', 'agent_settings'
	))):
	@property
	def is_windows(self):
		return True


def read_helm_settings(config, section_name):
	section = ConfigSection(config, section_name)

	windows_auth = read_windows_auth(section)

	ip = section['ip']
	db_instance_name = config.get(section_name, 'db-instance-name')
	if db_instance_name != '':
		host = r"%s\%s" % (ip, db_instance_name)
	else: 
		host = ip

	database = DbSettings(
		host=host,
		name=config.get(section_name, 'db-name'),
		port=config.get(section_name, 'db-port'),
		user=config.get(section_name, 'db-user'),
		password=config.get(section_name, 'db-password')
	)
	
	mail_settings = read_copy_mail_content_settings(section, is_windows=True)
	session_dir = section.get('session-dir', WINDOWS_SOURCE_DEFAULT_SESSION_DIR)

	return HelmConfig(
		id='helm', ip=ip, windows_auth=windows_auth, db=database, 
		migration_tool_dir=session_dir,
		migration_tool_name="HelmMigrationTool.exe",
		session_dir=session_dir,
		mail_settings=mail_settings,
		agent_settings=read_windows_agent_settings(config, section_name, session_dir)
	)


class HelmConnections:
	def __init__(self, conn_settings, migrator_server):
		self.conn_settings = conn_settings
		self._main_server = HelmSourceServer(
			'helm', self.conn_settings, migrator_server, winexe_runas=True
		)

	def db(self):
		return DatabaseWrapper(pymssql.connect(
			database=self.conn_settings.db.name,
			user=self.conn_settings.db.user,
			password=self.conn_settings.db.password,
			host=self.conn_settings.db.host,
			port=self.conn_settings.db.port
		).cursor())

	def get_main_source_server(self):
		return self._main_server

	@contextmanager
	def runner(self):
		"""Get runner of main Helm node"""

		with self.get_main_source_server().runner() as runner:
			yield runner
