# -*- coding: utf-8 -*-

import os
import sys
import codecs
import xml.dom.minidom
import xml.sax
import xml.sax.handler
from log_parser import BatchResultParser, StatusCode

STYLESHEET_FILENAME = "testlog.xsl"
LOG_VERSION			= '0.3.2'

class BuildXMLLogHandler(xml.sax.handler.ContentHandler):
	def __init__ (self, doc):
		self.doc			= doc
		self.elementStack	= []
		self.rootElements	= []

	def getRootElements (self):
		return self.rootElements

	def pushElement (self, elem):
		if len(self.elementStack) == 0:
			self.rootElements.append(elem)
		else:
			self.getCurElement().appendChild(elem)
		self.elementStack.append(elem)

	def popElement (self):
		self.elementStack.pop()

	def getCurElement (self):
		if len(self.elementStack) > 0:
			return self.elementStack[-1]
		else:
			return None

	def startDocument (self):
		pass

	def endDocument (self):
		pass

	def startElement (self, name, attrs):
		elem = self.doc.createElement(name)
		for name in attrs.getNames():
			value = attrs.getValue(name)
			elem.setAttribute(name, value)
		self.pushElement(elem)

	def endElement (self, name):
		self.popElement()

	def characters (self, content):
		# Discard completely empty content
		if len(content.strip()) == 0:
			return

		# Append as text node (not pushed to stack)
		if self.getCurElement() != None:
			txt = self.doc.createTextNode(content)
			self.getCurElement().appendChild(txt)

class LogErrorHandler(xml.sax.handler.ErrorHandler):
	def __init__ (self):
		pass

	def error (self, err):
		#print "error(%s)" % str(err)
		pass

	def fatalError (self, err):
		#print "fatalError(%s)" % str(err)
		pass

	def warning (self, warn):
		#print "warning(%s)" % str(warn)
		pass

def findFirstElementByName (nodes, name):
	for node in nodes:
		if node.nodeName == name:
			return node
		chFound = findFirstElementByName(node.childNodes, name)
		if chFound != None:
			return chFound
	return None

# Normalizes potentially broken (due to crash for example) log data to XML element tree
def normalizeToXml (result, doc):
	handler		= BuildXMLLogHandler(doc)
	errHandler	= LogErrorHandler()

	xml.sax.parseString(result.log, handler, errHandler)

	rootNodes = handler.getRootElements()

	# Check if we have TestCaseResult
	testCaseResult = findFirstElementByName(rootNodes, 'TestCaseResult')
	if testCaseResult == None:
		# Create TestCaseResult element
		testCaseResult = doc.createElement('TestCaseResult')
		testCaseResult.setAttribute('CasePath', result.name)
		testCaseResult.setAttribute('CaseType', 'SelfValidate') # \todo [pyry] Not recoverable..
		testCaseResult.setAttribute('Version', LOG_VERSION)
		rootNodes.append(testCaseResult)

	# Check if we have Result element
	resultElem = findFirstElementByName(rootNodes, 'Result')
	if resultElem == None:
		# Create result element
		resultElem = doc.createElement('Result')
		resultElem.setAttribute('StatusCode', result.statusCode)
		resultElem.appendChild(doc.createTextNode(result.statusDetails))
		testCaseResult.appendChild(resultElem)

	return rootNodes

def logToXml (inFile, outFile):
	parser	= BatchResultParser()
	results	= parser.parseFile(inFile)

	dstDoc			= xml.dom.minidom.Document()
	batchResultNode	= dstDoc.createElement('BatchResult')
	batchResultNode.setAttribute("FileName", os.path.basename(inFile))

	dstDoc.appendChild(batchResultNode)

	for result in results:
		# Normalize log to valid XML
		rootNodes = normalizeToXml(result, dstDoc)
		for node in rootNodes:
			batchResultNode.appendChild(node)

	# Summary
	countByStatusCode = {}
	for code in StatusCode.STATUS_CODES:
		countByStatusCode[code] = 0

	for result in results:
		countByStatusCode[result.statusCode] += 1

	summaryElem = dstDoc.createElement('ResultTotals')
	for code in StatusCode.STATUS_CODES:
		summaryElem.setAttribute(code, "%d" % countByStatusCode[code])
	summaryElem.setAttribute('All', "%d" % len(results))
	batchResultNode.appendChild(summaryElem)

	text = dstDoc.toprettyxml()

	out = codecs.open(outFile, "wb", encoding="utf-8")

	# Write custom headers
	out.write("<?xml version=\"1.0\"?>\n")
	out.write("<?xml-stylesheet href=\"%s\" type=\"text/xsl\"?>\n" % STYLESHEET_FILENAME)

	for line in text.splitlines()[1:]:
		out.write(line)
		out.write("\n")

	out.close()

if __name__ == "__main__":
	if len(sys.argv) != 3:
		print "%s: [test log] [dst file]" % sys.argv[0]
		sys.exit(-1)

	logToXml(sys.argv[1], sys.argv[2])
