/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



import java.io.FileWriter;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.io.PrintWriter;
import java.util.Vector;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Node;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
 *  This class will diff 2 Xml files.
 *
 *  @author   Stephen Mak
 */

public final class XmlDiff {

    private static final String PROPSFILE = "XmlDiff.properties";
    private static final String FILE1 = "XmlDiff.file1";
    private static final String FILE2 = "XmlDiff.file2";
    private static final String OUTPUT= "XmlDiff.output";
    private static final String IGNORE_TAGS= "XmlDiff.tags";

    private Properties props_ = null;
    private static PrintWriter writer_ = null;
    private String[] tags_ = null;
    private String file1_ = null;
    private String file2_ = null;

    /**
     *  Constructor.  Load the properties file.
     */

    public XmlDiff() throws IOException {

        Class c = this.getClass();
        InputStream is = c.getResourceAsStream(PROPSFILE);
        BufferedInputStream bis = new BufferedInputStream(is);
        props_ = new Properties();
        props_.load(bis);
        bis.close();

        String file1 = props_.getProperty(FILE1, "");
        String file2 = props_.getProperty(FILE2, "");
        String tagsString = props_.getProperty(IGNORE_TAGS, "");
        String output = props_.getProperty("debug.output", "System.out");
        setOutput(output);
        tags_ = parseTags(tagsString);
    }

    /**
     * diff 2 xml, but overwrite the property file's file1/2 setting with
     * the input argument
     */
    public boolean diff(String file1, String file2)  throws IOException {
        file1_ = file1;
        file2_ = file2;
        return diff();
    }

    public boolean diff() throws IOException {

        boolean result = false;

        writer_.println("parsing "+ file1_ + "...");
        // parse the Xml file
        Document doc1 = parseXml(file1_);

        writer_.println("parsing "+ file1_ + "...");
        Document doc2 = parseXml(file2_);

        if (doc1 != null && doc2 != null) {
          writer_.println("diffing "+ file1_ + " & " + file2_ + "...");
          result = compareNode(doc1, doc2);
        }
        return result;
    }

    private void diffLog(String errMsg, Node node1, Node node2) {

        String node1Str = "";
        String node2Str = "";

        if (node1 != null) {
            node1Str = "[Type]:" + nodeInfo(node1) +
                       " [Name]:" + node1.getNodeName();
            if (node1.getNodeValue() != null)
                node1Str += " [Value]:" + node1.getNodeValue();
        }

        if (node2 != null) {
            node2Str = "[Type]:" + nodeInfo(node2) +
                       " [Name]:" + node2.getNodeName();
            if (node2.getNodeValue() != null)
                node2Str += " [Value]:" + node2.getNodeValue();
        }

        writer_.println(errMsg);
        writer_.println("  Node1 - " + node1Str);
        writer_.println("  Node2 - " + node2Str);
    }

    private String nodeInfo(Node node) {

        String str = null;
        switch (node.getNodeType()) {

        	case Node.ELEMENT_NODE:
        	    str = "ELEMENT";
        	    break;
        	case Node.ATTRIBUTE_NODE:
        	    str = "ATTRIBUTE";
        	    break;
        	case Node.TEXT_NODE:
        	    str = "TEXT";
        	    break;
        	case Node.CDATA_SECTION_NODE:
        	    str = "CDATA_SECTION";
        	    break;
        	case Node.ENTITY_REFERENCE_NODE:
        	    str = "ENTITY_REFERENCE";
        	    break;
        	case Node.ENTITY_NODE:
        	    str = "ENTITY";
        	    break;
        	case Node.PROCESSING_INSTRUCTION_NODE:
        	    str = "PROCESSING_INSTRUCTION";
        	    break;
        	case Node.COMMENT_NODE:
        	    str = "COMMENT";
        	    break;
        	case Node.DOCUMENT_NODE:
        	    str = "DOCUMENT";
        	    break;
        	case Node.DOCUMENT_TYPE_NODE:
        	    str = "DOCUMENT_TYPE";
        	    break;
        	case Node.DOCUMENT_FRAGMENT_NODE:
        	    str = "DOCUMENT_FRAGMENT";
        	    break;
        	case Node.NOTATION_NODE:
        	    str = "NOTATION";
        	    break;
        }
        return str;
    }

    private boolean ignoreTag(String nodeName) {


        if (tags_ != null) {
            for (int i = 0; i < tags_.length; i++) {
                if (tags_[i].equals(nodeName))
                    return true;
            }
        }
        return false;
    }

    // for future use if we want to compare attributes
    private boolean attributesEqual(Node node1, Node node2) {
        return true;
    }

    private boolean compareNode(Node node1, Node node2) {
        boolean equal = false;

        while (true) {

            if (node1 == null && node2 == null) {
                equal = true;
                break;
            } else if (node1 == null || node2 == null) {
                diffLog("DIFF: one of the node is null", node1, node2);
                break;
            }

            if (node1.getNodeType() != node2.getNodeType()) {
                diffLog("DIFF: nodetype is different", node1, node2);
                break;
            }

            if (node1.getNodeName() == null && node2.getNodeName() == null) {
                // empty
            } else if (node1.getNodeName() == null ||
                       node2.getNodeName() == null) {
                diffLog("DIFF: one of the nodeName is null", node1, node2);
                break;
            } else if (!node1.getNodeName().equals(node2.getNodeName())) {
                diffLog("DIFF: nodeName is different", node1, node2);
                break;
            }

            if (ignoreTag(node1.getNodeName())) {
                diffLog("DIFF: Some tag(s) is ignored", node1, node2);
                equal = true;
                break;
            }

            if (node1.getNodeValue() == null && node2.getNodeValue() == null) {
                // empty
            } else if (node1.getNodeValue() == null ||
                       node2.getNodeValue() == null) {
                diffLog("DIFF: one of the nodevalue is null", node1, node2);
                break;
            } else if (!node1.getNodeValue().equals(node2.getNodeValue())) {
                diffLog("DIFF: nodeValue is different", node1, node2);
                break;
            }

            // try to compare attributes if necessary
            if (!attributesEqual(node1, node2))
                break;

            NodeList node1Children = node1.getChildNodes();
            NodeList node2Children = node2.getChildNodes();

            // number of children have to be the same
            if (node1Children == null && node2Children == null) {
                equal = true;
                break;
            }

            if (node1Children == null || node2Children == null) {
                diffLog("DIFF: one node's children is null", node1, node2);
                break;
            }

            if (node1Children.getLength() != node2Children.getLength())  {
                diffLog("DIFF: num of children is different", node1, node2);
                break;
            }

            // compare all the childrens
            equal = true;

            for (int i = 0; i < node1Children.getLength(); i++) {
                if (!compareNode(node1Children.item(i),
                                 node2Children.item(i))) {
                    equal = false;
                    break;
                }
            }
            break;
        }

        return equal;
    }

    private Document parseXml (String filename) throws IOException {

        Document w3cDocument = null;

        FileInputStream fis;

        try {
            fis = new FileInputStream(filename);
        } catch (FileNotFoundException ex) {
            ex.printStackTrace(writer_);
            writer_.println(ex.getMessage());
            return w3cDocument;
        }

        /** factory for DocumentBuilder objects */
        DocumentBuilderFactory factory = null;
        factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setValidating(false);

        /** DocumentBuilder object */
        DocumentBuilder builder = null;

        try {
            builder = factory.newDocumentBuilder();
        } catch (ParserConfigurationException ex) {
            ex.printStackTrace(writer_);
            writer_.println(ex.getMessage());
            return null;
        }


        builder.setErrorHandler(
            new org.xml.sax.ErrorHandler() {
                // ignore fatal errors (an exception is guaranteed)
                public void fatalError(SAXParseException e)
                    throws SAXException {
                    throw e;
                }

                public void error(SAXParseException e)
                    throws SAXParseException {
                    // make sure validation error is thrown.
                    throw e;
                }

                public void warning(SAXParseException e)
                    throws SAXParseException {
                }
            }
        );

        try {
            w3cDocument = builder.parse(fis);
            w3cDocument.getDocumentElement().normalize();
        } catch (SAXException ex) {
            ex.printStackTrace(writer_);
            writer_.println(ex.getMessage());
            return w3cDocument;
        }

        return w3cDocument;
    }

    private String [] parseTags(String tagsString) {
        Vector tagsVector = new Vector();
        if (tagsString.length() == 0)
            return null;

        int start = 0;
        int end = 0;
        // break the tag string into a vector of strings by words
        for (end = tagsString.indexOf(" ", start);
             end != -1 ;
             start = end + 1, end = tagsString.indexOf(" ", start)) {
            tagsVector.add(tagsString.substring(start,end));
        }

        tagsVector.add(tagsString.substring(start,tagsString.length()));

        // convert the vector to array
        String[] tags= new String[tagsVector.size()];
        tagsVector.copyInto(tags);

        return tags;
    }


    /**
     *  Set the output to the specified argument.
     *  This method is only used internally to prevent
     *  invalid string parameter.
     *
     *  @param   str   output specifier
     */
    private static void setOutput(String str) {

        if (writer_ == null) {

            if (str.equals("System.out")) {

                setOutput(System.out);

            } else if (str.equals("System.err")) {

                setOutput(System.err);

            } else {

                try {

                    setOutput(new FileWriter(str));

                } catch (IOException e) {

                    e.printStackTrace(System.err);
                }
            }
        }
    }

    /**
     *  Set the output to an OutputStream object.
     *
     *  @param   stream   OutputStream object
     */

    private static void setOutput(OutputStream stream) {

        setOutput(new OutputStreamWriter(stream));
    }

    /**
     *  Set the Writer object to manage the output.
     *
     *  @param   w   Writer object to write out
     */

    private static void setOutput(Writer w) {

        if (writer_ != null) {

            writer_.close();
        }

        writer_ = new PrintWriter(new BufferedWriter(w), true);
    }

    public static void main(String args[]) throws IOException {

        if (args.length != 0 && args.length != 2) {
            System.out.println("Usage: XmlDiff [<file1> <file2>].");
            return;
        }

        XmlDiff xmldiff = new XmlDiff();

        boolean same = false;
        if (args.length == 2) {
            same = xmldiff.diff(args[0], args[1]);
        } else {
            same = xmldiff.diff();
        }

        System.out.println("Diff result: " + same);
    }
}
