from collections import namedtuple
from datetime import datetime

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

DomainInfo = namedtuple('DomainInfo', (
	'gen_info',
))

DomainGenInfo = namedtuple('DomainGenInfo', (
	'creation_date', 'name', 'ascii_name', 'status', 'real_size', 'dns_ip_address',
	'htype', 'guid',
))


class DomainOperator(object):
	class Dataset(object):
		GEN_INFO = 'gen_info'
		# Not implemented: 'hosting', 'limits', 'stat', 'prefs', 'user', 'disk_usage', 'performance'

		values = [GEN_INFO]
	
	FilterAll = core.FilterAll
	FilterByName = core.declare_filter('FilterByName', 'name')
	FilterByDomainName = core.declare_filter('FilterByName', 'domain-name')
	FilterByName8 = core.declare_filter('FilterByName8', 'domain_name')
	FilterById = core.declare_filter('FilterById', 'id')

	class Get(core.operation_with_filter('Get', ('dataset',))):
		operator_name = 'domain'
		operation_name = 'get'
		min_api_version = '1.4.1.2'
		max_api_version = None

		def data_xml(self):
			return [
				elem('dataset', [elem(value) for value in DomainOperator.Dataset.values if value in self.dataset])
			]
			
		@classmethod
		def parse(cls, elem):
			return core.filter_owner_not_found_error(core.parse_result_set(elem, cls._parse_data, 'id'))
		
		@classmethod
		def _parse_data(cls, elem):
			domain_id = int(elem.findtext('id'))
			gen_info = cls._parse_gen_info(elem.find('data/gen_info'))
			
			return domain_id, DomainInfo(gen_info)
			
		@classmethod
		def _parse_gen_info(cls, elem):
			return DomainGenInfo(
				creation_date=datetime.strptime(elem.findtext('cr_date'), '%Y-%m-%d'),
				name=elem.findtext('name'), ascii_name=elem.findtext('ascii-name'),
				status=int(elem.findtext('status')), real_size=int(elem.findtext('real_size')),
				dns_ip_address=elem.findtext('dns_ip_address'),
				htype=elem.findtext('htype'), guid=elem.findtext('guid'),
			)

	DomainSetInfo = namedtuple('DomainSetInfo', ('user',))
	DomainSetUserInfo = namedtuple('DomainSetUserInfo', ('password',))

	class Set(core.operation_with_filter('Set', ('values',))):
		operator_name = 'domain'
		operation_name = 'set'
		min_api_version = '1.4.1.2'
		max_api_version = None

		def data_xml(self):
			return seq(
				elem('values', seq(
					if_not_none(self.values.user, lambda ui: elem('user', [
						if_not_none(ui.password, lambda p: text_elem('password', ui.password))
					]))
				))
			)
		
		@classmethod
		def parse(cls, elem):
			return core.Result.parse(elem.find('result'))