package org.eclipse.wst.wsdl.tests.util;


import java.io.IOException;
import java.io.PrintStream;

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

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


/**
 * @author Kihup Boo
 */
public class XMLDiff
{
  private PrintStream out = System.out;

  private boolean DIFF_ELEMENT_NODE_ONLY = false;

  public boolean diff(String file1, String file2) throws ParserConfigurationException, SAXException, IOException
  {
    return diff(file1, file2, false);
  }

  public boolean diff(String file1, String file2, boolean elementOnly) throws ParserConfigurationException, SAXException, IOException
  {
    Document doc1 = getDocument(file1);
    Document doc2 = getDocument(file2);
    DIFF_ELEMENT_NODE_ONLY = elementOnly;
    return diff(doc1, doc2);
  }

  public boolean diff(Document doc1, Document doc2)
  {
    Element root1 = doc1.getDocumentElement();
    Element root2 = doc2.getDocumentElement();
    return compareNodes(root1, root2);
  }

  private Document getDocument(String uri) throws ParserConfigurationException, SAXException, IOException
  {
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document doc = builder.parse(uri);
    return doc;
  }

  private boolean compareNodes(Node node1, Node node2)
  {
    if (DIFF_ELEMENT_NODE_ONLY)
    {
      // Compare only element nodes in the children.
      filterNonElementNodes(node1);
      filterNonElementNodes(node2);
    }

    if (node1.getNodeType() != node2.getNodeType() || node1.getNodeName() != node2.getNodeName())
    {
      println("Node type or node name is different:");
      println("Node 1: " + node1.getNodeName());
      println("Node 2: " + node2.getNodeName());
      return false;
    }

    if (!compareAttributes(node1, node2))
      return false;

    NodeList nodeList1 = node1.getChildNodes();
    NodeList nodeList2 = node2.getChildNodes();
    if (nodeList1.getLength() != nodeList2.getLength())
    {
      println("The number of children is different:");
      //println("Node 1: " + nodeList1.getLength());
      //println("Node 2: " + nodeList2.getLength());
      println("Node 1: " + node1.getNodeName());
      println("Node 2: " + node2.getNodeName());
      return false;
    }

    boolean result = true;
    int length = nodeList1.getLength();
    for (int i = 0; i < length; i++)
    {
      result = compareNodes(nodeList1.item(i), nodeList2.item(i));
      if (!result)
        return false;
    }
    return true;
  }

  private void filterNonElementNodes(Node node)
  {
    Node firstChild = node.getFirstChild();
    while (firstChild.getNodeType() != Node.ELEMENT_NODE)
    {
      node.removeChild(firstChild);
      firstChild = node.getFirstChild();
    }

    Node sibling = firstChild.getNextSibling();
    Node deleteMe = null;
    while (sibling != null)
    {
      if (sibling.getNodeType() != Node.ELEMENT_NODE)
      {
        deleteMe = sibling;
        sibling = sibling.getNextSibling();
        node.removeChild(deleteMe);
      }

    }
  }

  private boolean compareAttributes(Node node1, Node node2)
  {
    NamedNodeMap nodeMap1 = node1.getAttributes();
    NamedNodeMap nodeMap2 = node2.getAttributes();

    if (nodeMap1 == null || nodeMap2 == null)
    {
      if (nodeMap1 == null && nodeMap2 == null)
        return true;
      else
        return false;
    }

    if (nodeMap1.getLength() != nodeMap2.getLength())
    {
      println("The number of attributes is different:");
      println("Node 1: " + node1.getNodeName());
      println("Node 2: " + node2.getNodeName());
      return false;
    }

    Node attrNode1 = null;
    Node attrNode2 = null;
    int length = nodeMap1.getLength();
    for (int i = 0; i < length; i++)
    {
      attrNode1 = nodeMap1.item(i);
      attrNode2 = nodeMap2.getNamedItem(attrNode1.getNodeName());
      if (attrNode2 == null)
      {
        println("The attribute is not found in Node 2: " + attrNode1.getNodeName());
        println("Node 1: " + node1.getNodeName());
        println("Node 2: " + node2.getNodeName());
        return false;
      }
      else if (!attrNode1.getNodeValue().equals(attrNode2.getNodeValue()))
      {
        println("The attribute values are different:");
        println("Node 1: " + node1.getNodeName() + "," + attrNode1.getNodeValue());
        println("Node 2: " + node2.getNodeName() + "," + attrNode2.getNodeValue());
        return false;
      }
    }
    return true;
  }

  private void println(String s)
  {
    out.println(s);
  }
}