from collections import namedtuple

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

from .. import core

CustomerInfo = namedtuple('CustomerInfo', ('id', 'owner_id', 'login', 'guid', 'pname', 'email'))
CustomerAddInfo = namedtuple('CustomerAddInfo', ('gen_info',))
CustomerAddGenInfo = namedtuple('CustomerAddGenInfo', (
	'pname', 'login', 'passwd', 'email', 'owner_id',
	'address', 'city', 'country', 'pcode', 'phone', 
	'fax', 'cname', 'state', 'locale',
))
CustomerSetInfo = namedtuple('CustomerSetInfo', (
	'status',  # value from CustomerStatus
))
CustomerAddResult = namedtuple('CustomerAddResult', ('customer_id', 'guid'))

CustomerStatus = obj(
	DISABLED_BY_ADMIN=16,
)


class CustomerOperator(object):
	ERR_CLIENT_DOES_NOT_EXIST = 1013

	FilterAll = core.FilterAll
	FilterByLogin = core.declare_filter('FilterByLogin', 'login')
	FilterById = core.declare_filter('FilterByLogin', 'id')

	class Dataset(object):
		GEN_INFO = 'gen_info'

		values = [GEN_INFO]

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

		def data_xml(self):
			return seq(
				elem('dataset', [elem(i) for i in sort_list_by_another(self.dataset, CustomerOperator.Dataset.values)])
			)

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

		@classmethod
		def _parse_data(cls, elem):
			id = int(elem.findtext('id'))
			return (id, CustomerInfo(
				id=id,
				login=elem.findtext('data/gen_info/login'),
				guid=elem.findtext('data/gen_info/guid'),
				pname=elem.findtext('data/gen_info/pname'),
				email=elem.findtext('data/gen_info/email'),
				owner_id=elem.findtext('data/gen_info/owner-id')
			))

	class Add(core.operation('Add', 'customer_add_info')):
		operator_name = 'customer'
		operation_name = 'add'
		min_api_version = '1.6.4.0'
		max_api_version = None

		def inner_xml(self):
			return seq(
				elem('gen_info', seq(
					text_elem('cname', self.customer_add_info.gen_info.cname),
					text_elem('pname', self.customer_add_info.gen_info.pname),
					text_elem('login', self.customer_add_info.gen_info.login),
					text_elem('passwd', self.customer_add_info.gen_info.passwd),
					text_elem('phone', self.customer_add_info.gen_info.phone),
					text_elem('fax', self.customer_add_info.gen_info.fax),
					text_elem('email', self.customer_add_info.gen_info.email),
					text_elem('address', self.customer_add_info.gen_info.address),
					text_elem('city', self.customer_add_info.gen_info.city),
					text_elem('state', self.customer_add_info.gen_info.state),
					text_elem('pcode', self.customer_add_info.gen_info.pcode),
					text_elem('country', self.customer_add_info.gen_info.country),
					text_elem('locale', self.customer_add_info.gen_info.locale),
					text_elem('owner-id', self.customer_add_info.gen_info.owner_id),
				))
			)

		@classmethod
		def parse(cls, elem):
			return core.Result.parse(elem.find('result'), cls._parse_data)
		
		@classmethod
		def _parse_data(cls, elem):
			return CustomerAddResult(
				customer_id=elem.findtext('id'),
				guid=elem.findtext('guid')
			)

	class Set(core.operation_with_filter('Set', ('customer_set_info',))):
		operator_name = 'customer'
		operation_name = 'set'
		min_api_version = '1.6.4.0'
		max_api_version = None

		def data_xml(self):
			return seq(
				elem('values', [elem('gen_info', seq(
					text_elem('status', self.customer_set_info.status)
				))])
			)

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