#!/usr/bin/env python3

"""
This script applies patches to an XML file.

The patch file is itself an XML file.  It can have any root element name,
and uses XML attributes to specify if the elements in the file should replace
existing elements or add new ones.  An XPath attribute is used to specify
where the fix should be applied.  A <targetFile> element is required in the
patch file to specify the base name of the XML file the patches should be
applied to, though the targetFile element is handled outside of this script.

The only restriction is that since the type, xpath, and key attributes are
used to specify the patch placement the target XML cannot use those at a
top level element.

 It can apply patches in 5 ways:

 1) Add an element:
    Put in the element to add, along with the type='add' attribute
    and an xpath attribute specifying where the new element should go.

     <enumerationType type='add' xpath="./">
       <id>MY_TYPE</id>
     </enumerationType>

     This will add a new enumerationType element child to the root element.

 2) Replace an element:
    Put in the new element, with the type='replace' attribute
    and the XPath of the element you want to replace.

     <enumerator type='replace'
               xpath="enumerationType/[id='TYPE']/enumerator[name='XBUS']">
       <name>XBUS</name>
       <value>the new XBUS value</value>
     </enumerator>

    This will replace the enumerator element with name XBUS under the
    enumerationType element with ID TYPE.

 3) Remove an element:
    Put in the element to remove, with the type='remove' attribute and
    the XPath of the element you want to remove. The full element contents
    don't need to be specified, as the XPath is what locates the element.

    <enumerator type='remove'
                xpath='enumerationType[id='TYPE]/enumerator[name='DIMM']>
    </enumerator>

    This will remove the enumerator element with name DIMM under the
    enumerationType element with ID TYPE.

 4) Add child elements to a specific element.  Useful when adding several
    child elements at once.

    Use a type attribute of 'add-child' and specify the target parent with
    the xpath attribute.

     <enumerationType type="add-child" xpath="enumerationType/[id='TYPE']">
       <enumerator>
         <name>MY_NEW_ENUMERATOR</name>
         <value>23</value>
       </enumerator>
       <enumerator>
         <name>ANOTHER_NEW_ENUMERATOR</name>
         <value>99</value>
       </enumerator>
     </enumerationType>

     This will add 2 new <enumerator> elements to the enumerationType
     element with ID TYPE.

 5) Replace a child element inside another element, useful when replacing
    several child elements of the same parent at once.

    Use a type attribute of 'replace-child' and the xpath attribute
    as described above, and also use the key attribute to specify which
    element should be used to match on so the replace can be done.

     <enumerationType type="replace-child"
                      key="name"
                      xpath="enumerationType/[id='TYPE']">
       <enumerator>
         <name>OLD_ENUMERATOR</name>
         <value>newvalue</value>
       </enumerator>
       <enumerator>
         <name>ANOTHER_OLD_ENUMERATOR</name>
         <value>anothernewvalue</value>
       </enumerator>
     </enumerationType>

     This will replace the <enumerator> elements with the names of
     OLD_ENUMERATOR and ANOTHER_OLD_ENUMERATOR with the <enumerator>
     elements specified, inside of the enumerationType element with
     ID TYPE.
"""


import argparse
import sys

from lxml import etree


def delete_attrs(element, attrs):
    for a in attrs:
        try:
            del element.attrib[a]
        except Exception:
            pass


if __name__ == "__main__":
    parser = argparse.ArgumentParser("Applies fixes to XML files")
    parser.add_argument("-x", dest="xml", help="The input XML file")
    parser.add_argument("-p", dest="patch_xml", help="The patch XML file")
    parser.add_argument("-o", dest="output_xml", help="The output XML file")
    args = parser.parse_args()

    if not all([args.xml, args.patch_xml, args.output_xml]):
        parser.print_usage()
        sys.exit(-1)

    errors = []
    patch_num = 0
    patch_tree = etree.parse(args.patch_xml)
    patch_root = patch_tree.getroot()
    tree = etree.parse(args.xml)
    root = tree.getroot()

    for node in patch_root:
        if (
            (node.tag is etree.PI)
            or (node.tag is etree.Comment)
            or (node.tag == "targetFile")
        ):
            continue

        patch_num = patch_num + 1

        xpath = node.get("xpath", None)
        patch_type = node.get("type", "add")
        patch_key = node.get("key", None)
        delete_attrs(node, ["xpath", "type", "key"])

        print("Patch " + str(patch_num) + ":")

        try:
            if xpath is None:
                raise Exception("  E>  No XPath attribute found")

            target = tree.find(xpath)

            if target is None:
                raise Exception("  E>  Could not find XPath target " + xpath)

            if patch_type == "add":
                print("  Adding element " + target.tag + " to " + xpath)

                # The ServerWiz API is dependent on ordering for the
                # elements at the root node, so make sure they get appended
                # at the end.
                if (xpath == "./") or (xpath == "/"):
                    root.append(node)
                else:
                    target.append(node)

            elif patch_type == "remove":
                print("  Removing element " + xpath)
                parent = target.find("..")
                if parent is None:
                    raise Exception(
                        "  E>  Could not find parent of "
                        + xpath
                        + " so can't remove this element"
                    )
                parent.remove(target)

            elif patch_type == "replace":
                print("  Replacing element " + xpath)
                parent = target.find("..")
                if parent is None:
                    raise Exception(
                        "  E>  Could not find parent of "
                        + xpath
                        + " so can't replace this element"
                    )
                parent.remove(target)
                parent.append(node)

            elif patch_type == "add-child":
                for child in node:
                    print(
                        "  Adding a '"
                        + child.tag
                        + "' child element to "
                        + xpath
                    )
                    target.append(child)

            elif patch_type == "replace-child":
                if patch_key is None:
                    raise Exception(
                        "  E>  Patch type is replace-child, but"
                        " 'key' attribute isn't set"
                    )
                updates = []
                for child in node:
                    # Use the key to figure out which element to replace
                    key_element = child.find(patch_key)
                    for target_child in target:
                        for grandchild in target_child:
                            if (grandchild.tag == patch_key) and (
                                grandchild.text == key_element.text
                            ):
                                update = {}
                                update["remove"] = target_child
                                update["add"] = child
                                updates.append(update)

                for update in updates:
                    print(
                        "  Replacing a '"
                        + update["remove"].tag
                        + "' element in path "
                        + xpath
                    )
                    target.remove(update["remove"])
                    target.append(update["add"])

            else:
                raise Exception(
                    "  E>  Unknown patch type attribute found:  " + patch_type
                )

        except Exception as e:
            print(e)
            errors.append(e)

    tree.write(args.output_xml)

    if errors:
        print("Exiting with " + str(len(errors)) + " total errors")
        sys.exit(-1)
