/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.platform.xml;

import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;

/**
 * This class is used to compare if two DOM nodes are equal.
 */
public class XMLComparer {

    private boolean ignoreOrder;

    public XMLComparer() {
        super();
        ignoreOrder = false;
    }

    /**
     * Compare two DOM nodes.
     * @param control The first node in the comparison.
     * @param test The second node in the comparison.
     * @return Return true if the nodes are equal, else false.
     */
    public boolean isNodeEqual(Node control, Node test) {
        if (control == test) {
            return true;
        } else if ((null == control) || (null == test)) {
            return false;
        } else if (control.getNodeType() != test.getNodeType()) {
            return false;
        }
        switch (control.getNodeType()) {
        case (Node.ATTRIBUTE_NODE):
            return isAttributeEqual((Attr)control, (Attr)test);
        case (Node.CDATA_SECTION_NODE):
            return isTextEqual((Text)control, (Text)test);
        case (Node.COMMENT_NODE):
            return isCommentEqual((Comment)control, (Comment)test);
        case (Node.DOCUMENT_FRAGMENT_NODE):
            return isDocumentFragmentEqual((DocumentFragment)control, (DocumentFragment)test);
        case (Node.DOCUMENT_NODE):
            return isDocumentEqual((Document)control, (Document)test);
        case (Node.DOCUMENT_TYPE_NODE):
            return isDocumentTypeEqual((DocumentType)control, (DocumentType)test);
        case (Node.ELEMENT_NODE):
            return isElementEqual((Element)control, (Element)test);
        case (Node.ENTITY_NODE):
            return false;
        case (Node.ENTITY_REFERENCE_NODE):
            return isEntityReferenceEqual((EntityReference)control, (EntityReference)test);
        case (Node.NOTATION_NODE):
            return false;
        case (Node.PROCESSING_INSTRUCTION_NODE):
            return isProcessingInstructionEqual((ProcessingInstruction)control, (ProcessingInstruction)test);
        case (Node.TEXT_NODE):
            return isTextEqual((Text)control, (Text)test);
        default:
            return true;
        }
    }

    protected boolean isAttributeEqual(Attr control, Attr test) {
        if (!isStringEqual(control.getNamespaceURI(), test.getNamespaceURI())) {
            return false;
        }
        if (!isStringEqual(control.getName(), test.getName())) {
            return false;
        }
        if (!isStringEqual(control.getNodeValue(), test.getNodeValue())) {
            return false;
        }
        return true;
    }

    private boolean isCommentEqual(Comment control, Comment test) {
        if (!isStringEqual(control.getNodeValue(), test.getNodeValue())) {
            return false;
        }
        return true;
    }

    private boolean isDocumentEqual(Document control, Document test) {
        if (!isDocumentTypeEqual(control.getDoctype(), test.getDoctype())) {
            return false;
        }

        Element controlRootElement = control.getDocumentElement();
        Element testRootElement = test.getDocumentElement();
        if (controlRootElement == testRootElement) {
            return true;
        } else if ((null == controlRootElement) || (null == testRootElement)) {
            return false;
        }
        return isElementEqual(controlRootElement, testRootElement);
    }

    private boolean isDocumentFragmentEqual(DocumentFragment control, DocumentFragment test) {
        return isNodeListEqual(control.getChildNodes(), test.getChildNodes());
    }

    private boolean isDocumentTypeEqual(DocumentType control, DocumentType test) {
        if (control == test) {
            return true;
        } else if ((null == control) || (null == test)) {
            return false;
        }

        if (!isStringEqual(control.getName(), test.getName())) {
            return false;
        }
        if (!isStringEqual(control.getPublicId(), test.getPublicId())) {
            return false;
        }
        if (!isStringEqual(control.getSystemId(), test.getSystemId())) {
            return false;
        }

        return true;
    }

    private boolean isElementEqual(Element control, Element test) {
        if (!isStringEqual(control.getNamespaceURI(), test.getNamespaceURI())) {
            return false;
        }
        if (!isStringEqual(control.getTagName(), test.getTagName())) {
            return false;
        }

        // COMPARE ATTRIBUTES
        NamedNodeMap controlAttributes = control.getAttributes();
        NamedNodeMap testAttributes = test.getAttributes();
        int numberOfControlAttributes = controlAttributes.getLength();
        int numberOfTestAttributes = testAttributes.getLength();
        if (numberOfControlAttributes != numberOfTestAttributes) {
            return false;
        }
        Attr controlAttribute;
        Attr testAttribute;
        for (int x = 0; x < numberOfControlAttributes; x++) {
            controlAttribute = (Attr)controlAttributes.item(x);
            if (null == controlAttribute.getNamespaceURI()) {
                testAttribute = (Attr)testAttributes.getNamedItem(controlAttribute.getNodeName());
            } else {
                testAttribute = (Attr)testAttributes.getNamedItemNS(controlAttribute.getNamespaceURI(), controlAttribute.getLocalName());
            }
            if (null == testAttribute) {
                return false;
            } else if (!isAttributeEqual(controlAttribute, testAttribute)) {
                return false;
            }
        }

        // COMPARE CHILD NODES
        return isNodeListEqual(control.getChildNodes(), test.getChildNodes());
    }

    private boolean isEntityReferenceEqual(EntityReference control, EntityReference test) {
        if (!isStringEqual(control.getNodeName(), test.getNodeName())) {
            return false;
        }
        return true;
    }

    private boolean isProcessingInstructionEqual(ProcessingInstruction control, ProcessingInstruction test) {
        if (!isStringEqual(control.getTarget(), test.getTarget())) {
            return false;
        }
        if (!isStringEqual(control.getData(), test.getData())) {
            return false;
        }
        return true;
    }

    private boolean isTextEqual(Text control, Text test) {
        return isStringEqual(control.getNodeValue(), test.getNodeValue());
    }

    private boolean isNodeListEqual(NodeList control, NodeList test) {
        int numberOfControlNodes = control.getLength();
        if (numberOfControlNodes != test.getLength()) {
            return false;
        }
        if(ignoreOrder){
            for (int x = 0; x < numberOfControlNodes; x++) {
                if(!isNodeInNodeList(control.item(x), test)){
                    return false;
                }
            }
            for (int x = 0; x < numberOfControlNodes; x++) {
                if(!isNodeInNodeList(test.item(x), control)){
                    return false;
                }
            }
        }else{
            for (int x = 0; x < numberOfControlNodes; x++) {
                if (!isNodeEqual(control.item(x), test.item(x))) {
                    return false;
                }
            }
        }
        return true;
    }

    private boolean isNodeInNodeList(Node node, NodeList nodeList){
        int length = nodeList.getLength();
        for (int x = 0; x < length; x++) {
            Node nextNode = nodeList.item(x);
            if(isNodeEqual(node, nextNode)){
                return true;
            }
        }
        return false;
    }

    private boolean isStringEqual(String control, String test) {
        if (control == test) {
            return true;
        } else if (null == control) {
            return false;
        } else {
            return control.equals(test);
        }
    }

    public boolean isIgnoreOrder() {
        return ignoreOrder;
    }

    public void setIgnoreOrder(boolean ignoreOrder) {
        this.ignoreOrder = ignoreOrder;
    }
}
