from parallels.common import MigrationError
from parallels.common.connections.connections import Connections
from parallels.common.registry import Registry
from parallels.common.utils.config_utils import ConfigSection
from parallels.common.utils.entity import Entity


class MigratorConnections(Connections):
	def __init__(self, config, target_panel):
		super(MigratorConnections, self).__init__(config, target_panel)

	def get_information_servers(self):
		return {}

	def get_source_backup_paths(self):
		"""
		:rtype: dict[basestring, basestring]
		"""
		backup_paths = {}

		for section in self._get_source_backup_config_sections():
			if self._config.has_option(section, 'path'):
				# for full backup, just provide the path specified in config
				backup_paths[section] = self._config.get(section, 'path')
			elif self._config.has_option(section, 'light-path'):
				# for light backup, provide path, where full backup will be put
				session_files = Registry.get_instance().get_context().session_files
				backup_paths[section] = session_files.get_path_to_full_backup_created_from_light(section)

		return backup_paths

	def iter_source_light_backup_paths(self):
		"""
		:rtype: collections.Iterable[parallels.custom_panel_migrator.connections.LightBackupConfig]
		"""
		for section_name in self._get_source_backup_config_sections():
			section = ConfigSection(self._config, section_name)
			if 'light-path' in section:
				yield LightBackupConfig(
					source_id=section_name,
					path=section.get('light-path'),
					file_format=section.get('light-format', 'yaml').lower()
				)

	def _get_source_backup_config_sections(self):
		"""
		:rtype: list[basestring]
		"""
		if self._config.has_option('GLOBAL', 'source-backups'):
			list_str = self._config.get('GLOBAL', 'source-backups')
			if list_str.strip() != '':
				sections = map(str.strip, list_str.split(','))
				for section in sections:
					if not self._config.has_section(section):
						raise MigrationError(
							"Section '%s' specified in 'source-backups' option does not exist in config"
						)
				return sections
			else:
				return []
		else:
			return []

	def get_source_backup_path(self, backup_id):
		"""
		:type backup_id: basestring
		:rtype: basestring
		"""
		backup_paths = self.get_source_backup_paths()
		if backup_id not in backup_paths:
			raise Exception('Unable to retrieve path to backup "%s"' % backup_id)
		return backup_paths[backup_id]


class LightBackupConfig(Entity):
	def __init__(self, source_id, path, file_format):
		"""
		:type source_id: basestring
		:type path: basestring
		:type file_format: basestring
		"""
		self._source_id = source_id
		self._path = path
		self._file_format = file_format

	@property
	def source_id(self):
		"""Source ID - section name in migrator's configuration file

		:rtype: basestring
		"""
		return self._source_id

	@property
	def path(self):
		"""Path to the light backup

		:rtype: basestring
		"""
		return self._path

	@property
	def file_format(self):
		"""File format of the light backup: JSON or YAML (see FORMAT_* constants)

		:rtype: basestring
		"""
		return self._file_format