from parallels.source.shm_web_sn import messages
import logging
from collections import namedtuple
import xml.etree.ElementTree as et

from parallels.core.utils.common import ip

MoveList = namedtuple('MoveList', ('name', 'web_ip_v4', 'web_ip_v4_type', 'web_ip_v6', 'web_ip_v6_type'))

logger = logging.getLogger(__name__)

def read_move_list(fileobj):
	"""Methpd reads move list from file object.
	Example of move list XML:
	<move>
		<webspace name="test.tld">
			<web-ip type="shared">10.58.1.1</web-ip>
			<web-ip type="shared">::1</web-ip>
		</webspace>
	</move>
	:param fileobj: file object
	:return: MoveList
	"""

	webspace_name = None
	web_ip_v4 = None
	web_ip_v4_type = None
	web_ip_v6 = None
	web_ip_v6_type = None

	errors = []

	try:
		root_node = et.fromstring(fileobj.read())
	except Exception as err:
		logger.debug(u"Exception:", exc_info=True)
		errors.append(messages.FAILED_TO_READ_MOVE_LIST_FILE % (str(err),))
	else:
		for webspace_xml_node in root_node:
			if webspace_xml_node.tag == 'webspace':
				webspace_name = webspace_xml_node.attrib.get('name')
				if webspace_name is not None:
					if webspace_name.strip() != '':
						for web_ip_xml_node in webspace_xml_node:
							if web_ip_xml_node.tag == 'web-ip':
								target_ip = web_ip_xml_node.text
								target_ip_type = web_ip_xml_node.attrib.get('type')
								if target_ip_type not in [u'shared', u'exclusive']:
									errors.append(messages.TARGET_IP_HAS_INVALID_TYPE % (target_ip, target_ip_type,))
								if target_ip is not None:
									if ip.is_ipv4(target_ip):
										web_ip_v4 = target_ip
										web_ip_v4_type = target_ip_type
									elif ip.is_ipv6(target_ip):
										web_ip_v6 = target_ip
										web_ip_v6_type = target_ip_type
									else:
										errors.append(messages.TARGET_WEB_SERVICE_NODE_IP_NOT_VALID % (target_ip, webspace_name,))
								else:
									errors.append(messages.TARGET_WEB_SERVICE_NODE_IP_NOT_SPECIFIED % (webspace_name,))
							else:
								errors.append("Unknown service to migrate: <%s>" % (web_ip_xml_node.tag))
					else:
						errors.append(messages.ATTRIBUTE_NAME_OF_WEBSPACE_NODE_CAN_NOT_BE_EMPTY)
				else:
					errors.append(messages.ATTRIBUTE_NAME_OF_WEBSPACE_NODE_MUST_BE_SET)
			else:
				errors.append('Unknown node <%s>: expected <webspace> node' % (webspace_xml_node.tag,))

	move_list = MoveList(name=webspace_name,
						 web_ip_v4=web_ip_v4, web_ip_v4_type=web_ip_v4_type,
						 web_ip_v6=web_ip_v6, web_ip_v6_type=web_ip_v6_type)
	return move_list, errors


