from parallels.plesk.utils.xml_rpc.plesk import messages
from collections import namedtuple

from .. import core
from parallels.core.utils.common.xml import elem, text_elem, seq

BackupTask = namedtuple('BackupTask', ('id', 'status', 'started', 'prefix', 'filename', 'protocol'))


class BackupOperator(object):
	ONLY_HOSTING = 'only-hosting'
	ONLY_MAIL = 'only-mail'
	ALL = ''

	class BackupServer(core.operation('BackupServer', (
		'is_remote', 'prefix', 'description', 'split_size', 'mode', 'only_configuration')
	)):
		operator_name = 'backup-manager'
		operation_name = 'backup-server'
		min_api_version = '1.6.0.0'
		max_api_version = None

		def inner_xml(self):
			return seq(
				elem('remote') if self.is_remote else elem('local'),
				text_elem('prefix', self.prefix) if self.prefix is not None else None,
				text_elem('description', self.description),
				text_elem('split-size', self.split_size) if self.split_size is not None else None,

				elem('only-hosting') if self.mode == BackupOperator.ONLY_HOSTING \
				else elem('only-mail') if self.mode == BackupOperator.ONLY_MAIL \
				else None,

				elem('only-configuration') if self.only_configuration else None,
			)
			
		@classmethod
		def parse(cls, elem):
			return core.Result.parse(elem.find('result'), cls._parse_data)
		
		@classmethod
		def _parse_data(cls, elem):
			task_id = int(elem.findtext('task-id'))
			return task_id

	class GetTasksInfo(core.operation('GetTasksInfo', ('task_id,'))):
		operator_name = 'backup-manager'
		operation_name = 'get-tasks-info'
		min_api_version = '1.6.0.0'
		max_api_version = None

		def inner_xml(self):
			return [text_elem('task-id', self.task_id)]

		@classmethod
		def parse(cls, elem):
			return core.parse_result_set(elem, cls._parse_data, 'task')

		@classmethod
		def _parse_data(cls, elem):
			task = elem.find('task')

			if task.find('server') is None:
				raise Exception(messages.ONLY_SERVER_BACKUP_TASK_INFO_IS_SUPPORTED)

			return BackupTask(
				id=int(task.findtext('id')),
				status=task.findtext('status'),  # working | stopped | failed | finished
				started=task.findtext('started'),
				prefix=task.findtext('prefix'),
				filename=task.findtext('filename'),
				protocol=task.findtext('protocol'),  # ftp | local
			)

	class StopBackup(core.operation('StopBackup', ('task_id',))):
		operator_name = 'backup-manager'
		operation_name = 'stop-backup'
		min_api_version = '1.6.0.0'
		max_api_version = None

		def inner_xml(self):
			return [text_elem('task-id', self.task_id)]

		@classmethod
		def parse(cls, elem):
			return core.Result.parse(elem.find('result'))

	class _DownloadServerBackup(core.operation('DownloadFile', ('filename'))):
		"""Download server backup file operation.
		
		This operation is very special, it's response is non-standard, so it is
		handled in Client directly. See how this operation is used there.
		"""
		operator_name = 'backup-manager'
		operation_name = 'download-file'
		min_api_version = '1.6.0.0'
		max_api_version = None

		def inner_xml(self):
			return [elem('server'), text_elem('filename', self.filename)]
