/*
 * Copyright (c) 2014, 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
 */

package org.eclipse.persistence.testing.jaxb.beanvalidation;

import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * Compares contents of two xml files. Ignores whitespaces.
 *
 * @author jungi
 */
public final class ContentComparator {

    private static final Logger LOGGER = Logger.getLogger(ContentComparator.class.getName());

    /** Creates a new instance of ContentComparator */
    private ContentComparator() {
    }

    /**
     * Compares content of two xml files. Ignores whitespaces.
     *
     * @param f1 usually golden file
     * @param f2 other file which we want to compare against golden file (or any other file)
     * @return true if both files have the same content except of whitespaces
     */
    public static boolean equalsXML(File f1, File f2) {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document d1 = db.parse(f1);
            Document d2 = db.parse(f2);
            return compare(d1.getDocumentElement(), d2.getDocumentElement());
        } catch (ParserConfigurationException e) {
            LOGGER.log(Level.WARNING, "Exception from test - comparing XML files", e); //NOI18N
        } catch (SAXException e) {
            LOGGER.log(Level.WARNING, "Exception from test - comparing XML files", e); //NOI18N
        } catch (IOException e) {
            LOGGER.log(Level.WARNING, "Exception from test - comparing XML files", e); //NOI18N
        }
        return false;
    }

    private static boolean compare(Node n1, Node n2) {
        List<Node> l1 = new LinkedList<Node>();
        List<Node> l2 = new LinkedList<Node>();
        l1.add(n1);
        l2.add(n2);
        while (!l1.isEmpty() && !l2.isEmpty()) {
            Node m1 = l1.remove(0);
            Node m2 = l2.remove(0);
            //check basic things - node name, value, attributes - if they're OK, we can continue
            if (sameNode(m1, m2)) {
                //now compare children
                NodeList nl = m1.getChildNodes();
                for (int i = 0; i < nl.getLength(); i++) {
                    Node e = nl.item(i);
                    if (e.getNodeType() == Node.TEXT_NODE) {
                        //ignore empty places
                        if (e.getNodeValue().trim().equals("")) {
                            continue;
                        }
                    }
                    l1.add(nl.item(i));
                }
                nl = m2.getChildNodes();
                for (int i = 0; i < nl.getLength(); i++) {
                    Node e = nl.item(i);
                    if (e.getNodeType() == Node.TEXT_NODE) {
                        //ignore empty places
                        if (e.getNodeValue().trim().equals("")) {
                            continue;
                        }
                    }
                    l2.add(nl.item(i));
                }
            } else {
                //nodes are not equals - print some info
                LOGGER.warning("================================================"); //NOI18N
                LOGGER.warning("m1: " + m1.getNodeName() + "; \'" + m1.getNodeValue() + "\'"); //NOI18N
                LOGGER.warning("m2: " + m2.getNodeName() + "; \'" + m2.getNodeValue() + "\'"); //NOI18N
                LOGGER.warning("================================================"); //NOI18N
                return false;
            }
        }
        // check remains
        if (!l1.isEmpty()) {
            // missing nodes
            LOGGER.warning("================================================"); //NOI18N
            LOGGER.warning("Expected " + l1.size() + " more node(s):"); //NOI18N
            logNodes(l1);
            LOGGER.warning("================================================"); //NOI18N
            return false;
        } else if (!l2.isEmpty()) {
            // extra nodes
            LOGGER.warning("================================================"); //NOI18N
            LOGGER.warning("Got " + l2.size() + " more node(s) than expected:"); //NOI18N
            logNodes(l2);
            LOGGER.warning("================================================"); //NOI18N
            return false;
        } else {
            return true;
        }
    }

    //attrs, name, value
    private static boolean sameNode(Node n1, Node n2) {
        //check node name
        if (!n1.getNodeName().equals(n2.getNodeName())) {
            LOGGER.warning("================================================"); //NOI18N
            LOGGER.warning("Expected node: " + n1.getNodeName() + ", got: " + n2.getNodeName()); //NOI18N
            LOGGER.warning("================================================"); //NOI18N
            return false;
        }
        //check node value
        if (!((n1.getNodeValue() != null)
                ? n1.getNodeValue().equals(n2.getNodeValue())
                : (n2.getNodeValue() == null))) {
            LOGGER.warning("================================================"); //NOI18N
            LOGGER.warning("Expected node value: " + n1.getNodeValue() + ", got: " + n2.getNodeValue()); //NOI18N
            LOGGER.warning("================================================"); //NOI18N
            return false;
        }
        //check node attributes
        NamedNodeMap nnm1 = n1.getAttributes();
        NamedNodeMap nnm2 = n2.getAttributes();
        if ((nnm1 == null && nnm2 != null)
                || (nnm1 != null && nnm2 == null)) {
            return false;
        }
        if (nnm1 == null) {
            return true;
        }
        for (int i = 0; i < nnm1.getLength(); i++) {
            Node x = nnm1.item(i);
            Node y = nnm2.item(i);
            if (!(x.getNodeName().equals(y.getNodeName())
                    && x.getNodeValue().equals(y.getNodeValue()))) {
                //nodes are not equals - print some info
                LOGGER.warning("================================================"); //NOI18N
                LOGGER.warning("Expected attribute: " + x.getNodeName() + "=\'" +  x.getNodeValue() + "\'," //NOI18N
                        + " got: " + y.getNodeName() + "=\'" +  y.getNodeValue() + "\'"); //NOI18N
                LOGGER.warning("================================================"); //NOI18N
                return false;
            }
        }
        return true;
    }

    private static void logNodes(List<Node> nodes) {
        if (LOGGER.isLoggable(Level.WARNING)) {
            for(Node n : nodes) {
                LOGGER.warning("Node name: " + n.getNodeName()); //NOI18N
            }
        }
    }
}
