/*
 * Created on Mar 17, 2003
 *
 * To change this generated comment go to 
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package org.eclipse.etools.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;

/**
 * THE MASTER COPY of this class is in com.ibm.etools.commontests
 * Please update the copy in commontests and then copy this class to
 * where you need it if you are looking at a different copy
 * 
 * @author jsholl
 *
 * To change this generated comment go to 
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
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;
    }

}