from collections import namedtuple

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

DatabaseInfo = namedtuple('DatabaseInfo', ('id', 'name', 'type', 'webspace_id', 'db_server_id',))
AddDbResult = namedtuple('AddDbResult', ('id',))
DelDbResult = namedtuple('DelDbResult', ('id',))
DatabaseDefaultUserInfo = namedtuple('DatabaseDefaultUserInfo', ('db_id', 'db_user_id',))
DatabaseUserInfo = namedtuple('DatabaseUserInfo', ('id', 'login', 'db_id',))


class DatabaseOperator(object):
    class GetDb(core.operation_with_filter('GetDb')):
        FilterByWebspaceName = core.declare_filter('FilterByWebspaceName', 'webspace-name')

        operator_name = 'database'
        operation_name = 'get-db'
        min_api_version = '1.3.5.1'
        max_api_version = None

        @classmethod
        def parse(cls, elem):
            return core.parse_result_set(elem,  cls._parse_data, 'name')
        
        @classmethod
        def _parse_data(cls, elem):
            return DatabaseInfo(
                id=int(elem.findtext('id')),
                name=elem.findtext('name'),
                type=elem.findtext('type'),
                webspace_id=int(elem.findtext('webspace-id')),
                db_server_id=int(elem.findtext('db-server-id')),
            )

    class AddDb(core.operation('AddDb', ('webspace_id', 'name', 'type', 'db_server_id'))):
        operator_name = 'database'
        operation_name = 'add-db'
        min_api_version = '1.3.5.1'
        max_api_version = None

        def inner_xml(self):
            return seq(
                text_elem('webspace-id', self.webspace_id),
                text_elem('name', self.name),
                text_elem('type', self.type),
                text_elem('db-server-id', self.db_server_id)
            )

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

        @classmethod
        def _parse_data(cls, elem):
            return AddDbResult(id=elem.findtext('id'))

    class DelDb(core.operation_with_filter('DelDb')):
        FilterByDbIds = core.declare_filter('FilterByDbIds', 'id')

        operator_name = 'database'
        operation_name = 'del-db'
        min_api_version = '1.3.5.1'
        max_api_version = None

        @classmethod
        def parse(cls, elem):
            return core.parse_result_set(elem,  cls._parse_data, 'id')
        
        @classmethod
        def _parse_data(cls, elem):
            return DelDbResult(
                id=int(elem.findtext('id')),
            )

    class GetDbUsers(core.operation_with_filter('GetDbUsers')):
        operator_name = 'database'
        operation_name = 'get-db-users'
        min_api_version = '1.3.5.1'
        max_api_version = None

        FilterByDbIds = core.declare_filter('FilterByDbIds', 'db-id')

        @classmethod
        def parse(cls, elem):
            return core.parse_result_set(elem,  cls._parse_data, 'id')
        
        @classmethod
        def _parse_data(cls, elem):
            return DatabaseUserInfo(
                id=int(elem.findtext('id')),
                login=elem.findtext('login'),
                db_id=if_not_none(elem.findtext('db-id'), int),
            )

    class GetDefaultUser(core.operation_with_filter('GetDefaultUser')):
        FilterByDbIds = core.declare_filter('FilterByDbIds', 'db-id')

        operator_name = 'database'
        operation_name = 'get-default-user'
        min_api_version = '1.3.5.1'
        max_api_version = None
        
        @classmethod
        def parse(cls, elem):
            return core.parse_result_set(elem,  cls._parse_data, 'id')
        
        @classmethod
        def _parse_data(cls, elem):
            return DatabaseDefaultUserInfo(
                db_id=int(elem.findtext('filter-id')),
                db_user_id=int(elem.findtext('id')),
            )

    class SetDefaultUser(core.operation('SetDefaultUser', ('db_id', 'db_user_id',))):
        operator_name = 'database'
        operation_name = 'set-default-user'
        min_api_version = '1.3.5.1'
        max_api_version = None

        def inner_xml(self):
            return [
                text_elem('db-id', self.db_id),
                text_elem('default-user-id', self.db_user_id),
            ]

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