/*******************************************************************************
 * Copyright (c) 2004, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.common.tests.xml;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;

import org.w3c.dom.Attr;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;

public class DomComparitor {
    private static HashSet attributeList;

    public static String compareDoms(InputSource source1, InputSource source2, HashSet ignorableAtts, EntityResolver entityResolver) throws Exception {
//        attributeList = ignorableAtts;
//        DOMParser parser = new DOMParser();
//        if (entityResolver == null) {
//            parser.setEntityResolver(new EntityResolver() {
//                public InputSource resolveEntity(String arg0, String arg1) throws SAXException, IOException {
//                    return null;
//                }
//            });
//        } else {
//            parser.setEntityResolver(entityResolver);
//        }
//        parser.parse(source1);
//        Document doc1 = parser.getDocument();
//        parser.parse(source2);
//        Document doc2 = parser.getDocument();
//        return compareNodes(doc1, doc2);
    	return null;
    }
    public static String compareDoms(InputSource source1, InputSource source2, HashSet ignorableAtts) throws Exception {
        return compareDoms(source1, source2, ignorableAtts, null);
    }

    public static String compareDoms(InputSource source1, InputSource source2) throws Exception {
        return compareDoms(source1, source2, null);
    }

    public static String compareNodes(Node node1, Node node2) throws Exception {
        //        System.out.println("checking A:" + node1);
        //        System.out.println("checking B:" + node2);
        //        System.out.println("nodeType=" + node1.getNodeType());
        //        System.out.println("getNodeName=" + node1.getNodeName());
        //        System.out.println("getNodeValue=" + node1.getNodeValue());

        //Generic Node Testing 
        //        if (node1 == null && node2 == null)
        //            return null;
        //        else 
        if ((node1 != null && node2 == null) || node1 == null && node2 != null)
            return nullNodeEncountered(node1, node2);
        else if (node1.getNodeType() != node2.getNodeType()) {
            return mismatch("Node.getNodeType() " + node1.getNodeType() + " " + node2.getNodeType(), node1, node2);
        } else if (node1.getNodeName() != node2.getNodeName()) {
            return mismatch("Node.getNodeName() <" + node1.getNodeName() + "> <" + node2.getNodeName() + ">", node1, node2);
        } else if (!(node1.getNodeValue() == null && node2.getNodeValue() == null)) {
            if (node1.getNodeValue() == null) {
                return mismatch("Node.getNodeValue() node A is null", node1, node2);
            } else if (node2.getNodeValue() == null) {
                return mismatch("Node.getNodeValue() node B is null", node1, node2);
            } else if (!node1.getNodeValue().trim().equals(node2.getNodeValue().trim())) {
                return mismatch("Node.getNodeValue() <" + node1.getNodeValue() + "> <" + node2.getNodeValue() + ">", node1, node2);
            }
        }
        //TODO strengthen node comparisons as necessary
        //Specialized Node Testing
        switch (node1.getNodeType()) {
            case Node.TEXT_NODE :
            case Node.CDATA_SECTION_NODE :
                CharacterData cdata1 = (CharacterData) node1;
                CharacterData cdata2 = (CharacterData) node2;
                if (!cdata1.getData().trim().equals(cdata2.getData().trim())) {
                    return mismatch("CharacterData.getData() " + cdata1.getData() + " " + cdata2.getData(), node1, node2);
                }
                break;
            case Node.ATTRIBUTE_NODE :
                Attr attr1 = (Attr) node1;
                Attr attr2 = (Attr) node2;
                if (!attr1.getName().equals(attr2.getName())) {
                    return mismatch("Attr.getName() " + attr1.getName() + " " + attr2.getName(), node1, node2);
                } else if (!attr1.getValue().equals(attr2.getValue())) {
                    return mismatch("Attr.getValue() " + attr1.getValue() + " " + attr2.getValue(), node1, node2);
                } else if (attr1.getSpecified() != attr2.getSpecified()) {
                    return mismatch("Attr.getSpecified() " + attr1.getSpecified() + " " + attr2.getSpecified(), node1, node2);
                }
                break;
            case Node.DOCUMENT_NODE :
                Document doc1 = (Document) node1;
                Document doc2 = (Document) node2;
                String result = compareNodes(doc1.getDoctype(), doc2.getDoctype());
                if (result != null) {
                    return result;
                }
                break;
            case Node.DOCUMENT_TYPE_NODE :
                DocumentType docType1 = (DocumentType) node1;
                DocumentType docType2 = (DocumentType) node2;
                if (!docType1.getPublicId().equals(docType2.getPublicId())) {
                    return mismatch("DocumentType.getPublicId() " + docType1.getPublicId() + " " + docType2.getPublicId(), node1, node2);
                }
                break;
            case Node.PROCESSING_INSTRUCTION_NODE :
                ProcessingInstruction pInst1 = (ProcessingInstruction) node1;
                ProcessingInstruction pInst2 = (ProcessingInstruction) node2;
                //System.out.println("ProcessingInstruction todo");
                break;
            case Node.DOCUMENT_FRAGMENT_NODE :
                DocumentFragment frag1 = (DocumentFragment) node1;
                DocumentFragment frag2 = (DocumentFragment) node2;
                //System.out.println("DocumentFragment todo");
                break;

            case Node.ELEMENT_NODE :
            case Node.COMMENT_NODE :
            case Node.ENTITY_NODE :
            case Node.NOTATION_NODE :
                break;

        }

        //Recursion
        NamedNodeMap attributes1 = node1.getAttributes();
        NamedNodeMap attributes2 = node2.getAttributes();

        if (attributes1 != null && attributes2 != null) {
            ignoreAttributes(attributes1, attributes2);
            if (attributes1.getLength() != attributes2.getLength()) {
                return mismatch("getAttributes().getLength() " + attributes1.getLength() + " " + attributes2.getLength(), node1, node2);
            }
            for (int i = 0; i < attributes1.getLength(); i++) {
                Attr attr1 = (Attr) attributes1.item(i);
                Attr attr2 = (Attr) attributes2.item(i);
                String results = compareNodes(attr1, attr2);
				if (null != results) {
					return results;
				}
            }

        } else if (attributes1 != null || attributes2 != null) {
            return mismatch("getAttributes() null", node1, node2);
        }

        ArrayList children1 = getAsArrayList(node1.getChildNodes());
        ArrayList children2 = getAsArrayList(node2.getChildNodes());

        ignoreComments(children1);
        ignoreComments(children2);

        ignoreEmptyTextNodes(children1);
        ignoreEmptyTextNodes(children2);

        if (children1.size() != children2.size()) {
            return mismatch("Node.hasChildNodes() " + children1.size() + " " + children2.size(), node1, node2);
        }

        for (int i = 0; i < children1.size(); i++) {
            Node child1 = (Node) children1.get(i);
            Node child2 = (Node) children2.get(i);
            String results = compareNodes(child1, child2);
            if (null != results) {
                return results;
            }
        }
        return null;
    }

    private static ArrayList getAsArrayList(NodeList originalList) {
        ArrayList newList = new ArrayList();
        if (originalList != null) {
            for (int i = 0; i < originalList.getLength(); i++) {
                newList.add(originalList.item(i));
            }
        }
        return newList;
    }

    private static void ignoreComments(ArrayList list) {
        ArrayList toRemove = new ArrayList();
        for (int i = 0; i < list.size(); i++) {
            Node node = (Node) list.get(i);
            if (node.getNodeType() == Node.COMMENT_NODE) {
                toRemove.add(node);
            }
        }
        for (int i = 0; i < toRemove.size(); i++) {
            list.remove(toRemove.get(i));
        }
    }

    private static void ignoreEmptyTextNodes(ArrayList list) {
        ArrayList toRemove = new ArrayList();
        for (int i = 0; i < list.size(); i++) {
            Node node = (Node) list.get(i);
            if (node.getNodeType() == Node.TEXT_NODE && (node.getNodeValue() == null || node.getNodeValue().trim().equals(""))) {
                toRemove.add(node);
            }
        }
        for (int i = 0; i < toRemove.size(); i++) {
            list.remove(toRemove.get(i));
        }
    }

    /**
     * @param attributes1
     */
    private static void ignoreAttributes(NamedNodeMap attributes1, NamedNodeMap attributes2) {
        if (attributeList != null) {
            Iterator it = attributeList.iterator();
            String ignore;
            while (it.hasNext()) {
                ignore = (String) it.next();
                if (attributes1.getNamedItem(ignore) != null)
                    attributes1.removeNamedItem(ignore);
                if (attributes2.getNamedItem(ignore) != null)
                    attributes2.removeNamedItem(ignore);
            }
        }
    }

    public static String nullNodeEncountered(Node node1, Node node2) {
        String message = "Null node encountered";
        Node nonNullNode = node1 == null ? node2 : node1;
        char source = node1 == null ? 'B' : 'A';
        while (nonNullNode != null) {
            message += source + nonNullNode.getNodeName() + "\n";
            nonNullNode = nonNullNode.getParentNode();
        }
        return message;
    }

    public static String nodeNotCompared(Node node) {
        String message = "Node node compared:";
        while (node != null) {
            message += node.getNodeName() + "\n";
            node = node.getParentNode();
        }

        return message;
    }

    public static String mismatch(String mismatchtype, Node node1, Node node2) throws Exception {
        String message = "Nodes A and B do not match because of node." + mismatchtype + "\n";
        while (node1 != null && node2 != null) {
            message += "A:" + node1.getNodeName() + "\n";
            message += "B:" + node2.getNodeName() + "\n";
            node1 = node1.getParentNode();
            node2 = node2.getParentNode();
        }

        return message;
    }

}