#!/usr/bin/env python
# -----------------------------------------------------------------------------
# Copyright (C) 2002-2004 Networks Associates Technology Inc.
# All rights reserved.
#
# $Date: 2004/07/13 15:20:02 $
# $Revision: 1.3 $
# -----------------------------------------------------------------------------

import os, sys, libxml2, getopt

def usage():
	print >>sys.stderr, "usage: %s [OPTION] XML_CONF INPUT_FILE OUTPUTFILE" % (os.path.basename(sys.argv[0]))
	print >>sys.stderr, "XML_CONF:				  the XML replacement ruleset"
	print >>sys.stderr, "INPUT_FILE:			  the XML template file"
	print >>sys.stderr, "OUTPUT_FILE:			  the XML output file"
	print >>sys.stderr, "OPTIONS:"
	print >>sys.stderr, "  -h, --help			  displays this help"
try:
	opts, args = getopt.getopt(sys.argv[1:], "hx:", ["help", "xpath="])
	if len(args) != 3:
		raise RuntimeError
except:
	usage()
	sys.exit(-1)

xpath = None
file = None
for o, a in opts:
	if o in ("-h", "--help"):
		usage()
		sys.exit(0)
xml_path = args[0]
in_path = args[1]
out_path = args[2]

try:
	try:
		xml_doc = libxml2.parseFile(xml_path)
	except:
		print "unable to parse the xml rule file"
		sys.exit(-1)
		
	try:
		in_doc = libxml2.parseFile(in_path)
	except:
		print "unable to parse the xml input file"
		sys.exit(-1)
	
	ictxt = xml_doc.xpathNewContext()
	octxt = in_doc.xpathNewContext()

	# simple transformations
	simpletransforms = ictxt.xpathEval("/ReplaceXml/Value")
	for t in simpletransforms:
		xpath = t.prop("xpath")
		nval = t.prop("value")
		found = octxt.xpathEval(xpath)
		for f in found:
			f.setContent(nval)
	# adding attributes
	additions = ictxt.xpathEval("/ReplaceXml/Append")
	for t in additions:
		xpath = t.prop("xpath")
		nval = t.prop("value")
		attr = t.prop("attr")
		found = octxt.xpathEval(xpath)
		for f in found:
			f.setProp(attr,nval)
	# replacements
	replacements = ictxt.xpathEval("/ReplaceXml/Children")
	for r in replacements:
		xpath = r.prop("xpath")
		found = octxt.xpathEval(xpath)
		for f in found:
			# remove evrything
			child = f.children
			children = []
			while child != None:
				children.append(child)
				child = child.next
			for child in children:
				child.unlinkNode()
			# copy the nodes
			child = r.children
			while child != None:
				nchild = child.copyNode(True)
				nchild.unlinkNode()
				f.addChild(nchild)
				child = child.next
	in_doc.saveFile(out_path)
except Exception, details:
	print "ouch!", details
	sys.exit(1)
	
