from collections import namedtuple

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

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)]
