from collections import namedtuple

from .. import core
from parallels.plesk.utils.xml_rpc.expand.core import parse_result_set
from parallels.core.utils.common import sort_list_by_another
from parallels.core.utils.common.xml import elem, text_elem

ClientData = namedtuple('Client', ('id', 'info', 'personal_info'))


class ClientOperator(object):
    class Get(namedtuple('Get', ('filter', 'dataset'))):
        class FilterAll:
            def inner_xml(self): return []

        class Dataset:
            INFO = 'info'
            PERSONAL_INFO = 'personal_info'
            LIMITS = 'limits'
            PERMISSIONS = 'permissions'
            PREFERENCES = 'preferences'
            PACKAGES = 'packages'
            STATISTICS = 'statistics'
            IPPOOL = 'ippool'

            values = [INFO, PERSONAL_INFO, LIMITS, PERMISSIONS, PREFERENCES, PACKAGES, STATISTICS, IPPOOL]

        operator_name = 'exp_plesk_multi_client'
        operation_name = 'get'

        def inner_xml(self):
            return [
                elem('filter', self.filter.inner_xml()),
                elem('dataset', [elem(i) for i in sort_list_by_another(self.dataset, self.Dataset.values)])
            ]
            
        @classmethod
        def parse(cls, elem):
            return parse_result_set(elem, cls._parse_data)
        
        @classmethod
        def _parse_data(cls, elem):
            return ClientData(
                id=int(elem.findtext('client_id')),
                info=dict((node.tag, node.text) for node in elem.findall('data/info/')),
                personal_info=dict((node.tag, node.text) for node in elem.findall('data/personal_info/'))
            )

    class InstanceGet(namedtuple('InstanceGet', ('filter'))):
        class FilterByClientId(namedtuple('FilterByClientId', ('ids',))):
            def inner_xml(self): return [text_elem('client_id', rid) for rid in self.ids]

        operator_name = 'exp_plesk_multi_client'
        operation_name = 'instance'

        def inner_xml(self):
            return [elem('get',
                [elem('filter', self.filter.inner_xml())]
            )]

        @classmethod
        def parse(cls, elem):
            return [core.Result.parse(r, cls._parse_data) for r in elem.findall('get/result')]
        
        @classmethod
        def _parse_data(cls, elem):
            return (
                int(elem.findtext('client_id')),
                [int(plesk_client_id_node.text) for plesk_client_id_node in elem.findall('data/plesk_client_id')]
            )
