# this is required as we have "xml.py" file in the current package which replaces Python "xml" module on Python 2.7
from __future__ import absolute_import 

# Borrowed from
# https://bitbucket.org/formencode/official-formencode/src/3be5078c6030/formencode/doctest_xml_compare.py#cl-70

import xml.etree.ElementTree as ET


def reporter(msg):
	raise Exception(msg)


def compare_xml(x1, x2, reporter=reporter):
	if x1.tag != x2.tag:
		if reporter:
			reporter('Tags do not match: %s and %s' % (x1.tag, x2.tag))
		return False
	for name, value in x1.attrib.items():
		if x2.attrib.get(name) != value:
			if reporter:
				reporter(
					'Attributes do not match: %s=%r, %s=%r' % (
						name, value, name, x2.attrib.get(name)
					)
				)
			return False
	for name in x2.attrib:
		if name not in x1.attrib:
			if reporter:
				reporter('x2 has an attribute x1 is missing: %s' % name)
			return False
	if not text_compare(x1.text, x2.text):
		if reporter:
			reporter('text: %r != %r' % (x1.text, x2.text))
		return False
	if not text_compare(x1.tail, x2.tail):
		if reporter:
			reporter('tail: %r != %r' % (x1.tail, x2.tail))
		return False
	cl1 = x1.getchildren()
	cl2 = x2.getchildren()
	if len(cl1) != len(cl2):
		if reporter:
			reporter(
				'number of children of "%s" element differs, %i != %i' % (
					x1.tag, len(cl1), len(cl2)
				)
			)
		return False
	i = 0
	for c1, c2 in zip(cl1, cl2):
		i += 1
		if not compare_xml(c1, c2, reporter=reporter):
			if reporter:
				reporter('children %i do not match: %s' % (i, c1.tag))
			return False
	return True


def text_compare(t1, t2):
	if not t1 and not t2:
		return True
	if t1 == '*' or t2 == '*':
		return True
	return (t1 or '').strip() == (t2 or '').strip()


def make_xml(s):
	return ET.XML('<xml>%s</xml>' % s)


def make_string(xml):
	if isinstance(xml, (str, unicode)):
		xml = make_xml(xml)
	s = ET.tostring(xml)
	if s == '<xml />':
		return ''
	assert s.startswith('<xml>') and s.endswith('</xml>'), repr(s)
	return s[5:-6]
