/**
 * 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.
 */
package org.apache.xml.security.signature;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.Set;

import org.apache.xml.security.c14n.helper.AttrCompare;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;

/**
 * Class XMLSignatureInputDebugger
 */
public class XMLSignatureInputDebugger {

    /** Field _xmlSignatureInput */
    private Set<Node> xpathNodeSet;

    private Set<String> inclusiveNamespaces;

    /** Field writer */
    private Writer writer;

    /** The HTML Prefix* */
    static final String HTMLPrefix =
        "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
        + "<html>\n"
        + "<head>\n"
        + "<title>Caninical XML node set</title>\n"
        + "<style type=\"text/css\">\n"
        + "<!-- \n"
        + ".INCLUDED { \n"
        + "   color: #000000; \n"
        + "   background-color: \n"
        + "   #FFFFFF; \n"
        + "   font-weight: bold; } \n"
        + ".EXCLUDED { \n"
        + "   color: #666666; \n"
        + "   background-color: \n"
        + "   #999999; } \n"
        + ".INCLUDEDINCLUSIVENAMESPACE { \n"
        + "   color: #0000FF; \n"
        + "   background-color: #FFFFFF; \n"
        + "   font-weight: bold; \n"
        + "   font-style: italic; } \n"
        + ".EXCLUDEDINCLUSIVENAMESPACE { \n"
        + "   color: #0000FF; \n"
        + "   background-color: #999999; \n"
        + "   font-style: italic; } \n"
        + "--> \n"
        + "</style> \n"
        + "</head>\n"
        + "<body bgcolor=\"#999999\">\n"
        + "<h1>Explanation of the output</h1>\n"
        + "<p>The following text contains the nodeset of the given Reference before it is canonicalized. There exist four different styles to indicate how a given node is treated.</p>\n"
        + "<ul>\n"
        + "<li class=\"INCLUDED\">A node which is in the node set is labeled using the INCLUDED style.</li>\n"
        + "<li class=\"EXCLUDED\">A node which is <em>NOT</em> in the node set is labeled EXCLUDED style.</li>\n"
        + "<li class=\"INCLUDEDINCLUSIVENAMESPACE\">A namespace which is in the node set AND in the InclusiveNamespaces PrefixList is labeled using the INCLUDEDINCLUSIVENAMESPACE style.</li>\n"
        + "<li class=\"EXCLUDEDINCLUSIVENAMESPACE\">A namespace which is in NOT the node set AND in the InclusiveNamespaces PrefixList is labeled using the INCLUDEDINCLUSIVENAMESPACE style.</li>\n"
        + "</ul>\n" + "<h1>Output</h1>\n" + "<pre>\n";

    /** HTML Suffix * */
    static final String HTMLSuffix = "</pre></body></html>";

    static final String HTMLExcludePrefix = "<span class=\"EXCLUDED\">";

    static final String HTMLIncludePrefix = "<span class=\"INCLUDED\">";

    static final String HTMLIncludeOrExcludeSuffix = "</span>";

    static final String HTMLIncludedInclusiveNamespacePrefix = "<span class=\"INCLUDEDINCLUSIVENAMESPACE\">";

    static final String HTMLExcludedInclusiveNamespacePrefix = "<span class=\"EXCLUDEDINCLUSIVENAMESPACE\">";

    private static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;

    private static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;

    private static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;

    static final AttrCompare ATTR_COMPARE = new AttrCompare();

    /**
     * Constructor XMLSignatureInputDebugger
     *
     * @param xmlSignatureInput the signature to pretty print
     */
    public XMLSignatureInputDebugger(XMLSignatureInput xmlSignatureInput) {
        if (!xmlSignatureInput.isNodeSet()) {
            this.xpathNodeSet = null;
        } else {
            this.xpathNodeSet = xmlSignatureInput.getInputNodeSet();
        }
    }

    /**
     * Constructor XMLSignatureInputDebugger
     *
     * @param xmlSignatureInput the signatur to pretty print
     * @param inclusiveNamespace
     */
    public XMLSignatureInputDebugger(
        XMLSignatureInput xmlSignatureInput,
        Set<String> inclusiveNamespace
    ) {
        this(xmlSignatureInput);
        this.inclusiveNamespaces = inclusiveNamespace;
    }

    /**
     * Method getHTMLRepresentation
     *
     * @return The HTML Representation.
     * @throws XMLSignatureException
     */
    public String getHTMLRepresentation() throws XMLSignatureException {
        if (this.xpathNodeSet == null || this.xpathNodeSet.isEmpty()) {
            return HTMLPrefix + "<blink>no node set, sorry</blink>" + HTMLSuffix;
        }

        // get only a single node as anchor to fetch the owner document
        Node n = this.xpathNodeSet.iterator().next();

        Document doc = XMLUtils.getOwnerDocument(n);

        try {
            this.writer = new StringWriter();

            this.canonicalizeXPathNodeSet(doc);
            this.writer.close();

            return this.writer.toString();
        } catch (IOException ex) {
            throw new XMLSignatureException(ex);
        } finally {
            this.xpathNodeSet = null;
            this.writer = null;
        }
    }

    /**
     * Method canonicalizeXPathNodeSet
     *
     * @param currentNode
     * @throws XMLSignatureException
     * @throws IOException
     */
    private void canonicalizeXPathNodeSet(Node currentNode)
        throws XMLSignatureException, IOException {

        int currentNodeType = currentNode.getNodeType();
        switch (currentNodeType) {


        case Node.ENTITY_NODE:
        case Node.NOTATION_NODE:
        case Node.DOCUMENT_FRAGMENT_NODE:
        case Node.ATTRIBUTE_NODE:
            throw new XMLSignatureException("empty", new Object[]{"An incorrect node was provided for c14n: " + currentNodeType});
        case Node.DOCUMENT_NODE:
            this.writer.write(HTMLPrefix);

            for (Node currentChild = currentNode.getFirstChild();
                currentChild != null; currentChild = currentChild.getNextSibling()) {
                this.canonicalizeXPathNodeSet(currentChild);
            }

            this.writer.write(HTMLSuffix);
            break;

        case Node.COMMENT_NODE:
            if (this.xpathNodeSet.contains(currentNode)) {
                this.writer.write(HTMLIncludePrefix);
            } else {
                this.writer.write(HTMLExcludePrefix);
            }

            int position = getPositionRelativeToDocumentElement(currentNode);

            if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
                this.writer.write("\n");
            }

            this.outputCommentToWriter((Comment) currentNode);

            if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
                this.writer.write("\n");
            }

            this.writer.write(HTMLIncludeOrExcludeSuffix);
            break;

        case Node.PROCESSING_INSTRUCTION_NODE:
            if (this.xpathNodeSet.contains(currentNode)) {
                this.writer.write(HTMLIncludePrefix);
            } else {
                this.writer.write(HTMLExcludePrefix);
            }

            position = getPositionRelativeToDocumentElement(currentNode);

            if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
                this.writer.write("\n");
            }

            this.outputPItoWriter((ProcessingInstruction) currentNode);

            if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
                this.writer.write("\n");
            }

            this.writer.write(HTMLIncludeOrExcludeSuffix);
            break;

        case Node.TEXT_NODE:
        case Node.CDATA_SECTION_NODE:
            if (this.xpathNodeSet.contains(currentNode)) {
                this.writer.write(HTMLIncludePrefix);
            } else {
                this.writer.write(HTMLExcludePrefix);
            }

            outputTextToWriter(currentNode.getNodeValue());

            for (Node nextSibling = currentNode.getNextSibling();
                nextSibling != null
                && (nextSibling.getNodeType() == Node.TEXT_NODE
                    || nextSibling.getNodeType() == Node.CDATA_SECTION_NODE);
                nextSibling = nextSibling.getNextSibling()) {
                /*
                 * The XPath data model allows to select only the first of a
                 * sequence of mixed text and CDATA nodes. But we must output
                 * them all, so we must search:
                 *
                 * @see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6329
                 */
                this.outputTextToWriter(nextSibling.getNodeValue());
            }

            this.writer.write(HTMLIncludeOrExcludeSuffix);
            break;

        case Node.ELEMENT_NODE:
            Element currentElement = (Element) currentNode;

            if (this.xpathNodeSet.contains(currentNode)) {
                this.writer.write(HTMLIncludePrefix);
            } else {
                this.writer.write(HTMLExcludePrefix);
            }

            this.writer.write("&lt;");
            this.writer.write(currentElement.getTagName());

            this.writer.write(HTMLIncludeOrExcludeSuffix);

            // we output all Attrs which are available
            NamedNodeMap attrs = currentElement.getAttributes();
            int attrsLength = attrs.getLength();
            Attr attrs2[] = new Attr[attrsLength];

            for (int i = 0; i < attrsLength; i++) {
                attrs2[i] = (Attr)attrs.item(i);
            }

            Arrays.sort(attrs2, ATTR_COMPARE);
            Object[] attrs3 = attrs2;

            for (int i = 0; i < attrsLength; i++) {
                Attr a = (Attr) attrs3[i];
                boolean included = this.xpathNodeSet.contains(a);
                boolean inclusive = this.inclusiveNamespaces.contains(a.getName());

                if (included) {
                    if (inclusive) {
                        // included and inclusive
                        this.writer.write(HTMLIncludedInclusiveNamespacePrefix);
                    } else {
                        // included and not inclusive
                        this.writer.write(HTMLIncludePrefix);
                    }
                } else {
                    if (inclusive) {
                        // excluded and inclusive
                        this.writer.write(HTMLExcludedInclusiveNamespacePrefix);
                    } else {
                        // excluded and not inclusive
                        this.writer.write(HTMLExcludePrefix);
                    }
                }

                this.outputAttrToWriter(a.getNodeName(), a.getNodeValue());
                this.writer.write(HTMLIncludeOrExcludeSuffix);
            }

            if (this.xpathNodeSet.contains(currentNode)) {
                this.writer.write(HTMLIncludePrefix);
            } else {
                this.writer.write(HTMLExcludePrefix);
            }

            this.writer.write("&gt;");

            this.writer.write(HTMLIncludeOrExcludeSuffix);

            // traversal
            for (Node currentChild = currentNode.getFirstChild();
                currentChild != null;
                currentChild = currentChild.getNextSibling()) {
                this.canonicalizeXPathNodeSet(currentChild);
            }

            if (this.xpathNodeSet.contains(currentNode)) {
                this.writer.write(HTMLIncludePrefix);
            } else {
                this.writer.write(HTMLExcludePrefix);
            }

            this.writer.write("&lt;/");
            this.writer.write(currentElement.getTagName());
            this.writer.write("&gt;");

            this.writer.write(HTMLIncludeOrExcludeSuffix);
            break;

        case Node.DOCUMENT_TYPE_NODE:
        default:
            break;
        }
    }

    /**
     * Checks whether a Comment or ProcessingInstruction is before or after the
     * document element. This is needed for prepending or appending "\n"s.
     *
     * @param currentNode
     *            comment or pi to check
     * @return NODE_BEFORE_DOCUMENT_ELEMENT,
     *         NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT or
     *         NODE_AFTER_DOCUMENT_ELEMENT
     * @see #NODE_BEFORE_DOCUMENT_ELEMENT
     * @see #NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT
     * @see #NODE_AFTER_DOCUMENT_ELEMENT
     */
    private int getPositionRelativeToDocumentElement(Node currentNode) {
        if (currentNode == null) {
            return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
        }

        Document doc = currentNode.getOwnerDocument();

        if (currentNode.getParentNode() != doc) {
            return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
        }

        Element documentElement = doc.getDocumentElement();

        if (documentElement == null) {
            return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
        }

        if (documentElement == currentNode) {
            return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
        }

        for (Node x = currentNode; x != null; x = x.getNextSibling()) {
            if (x == documentElement) {
                return NODE_BEFORE_DOCUMENT_ELEMENT;
            }
        }

        return NODE_AFTER_DOCUMENT_ELEMENT;
    }

    /**
     * Normalizes an {@link Attr}ibute value
     *
     * The string value of the node is modified by replacing
     * <UL>
     * <LI>all ampersands (&) with <CODE>&amp;amp;</CODE></LI>
     * <LI>all open angle brackets (<) with <CODE>&amp;lt;</CODE></LI>
     * <LI>all quotation mark characters with <CODE>&amp;quot;</CODE></LI>
     * <LI>and the whitespace characters <CODE>#x9</CODE>, #xA, and #xD,
     * with character references. The character references are written in
     * uppercase hexadecimal with no leading zeroes (for example, <CODE>#xD</CODE>
     * is represented by the character reference <CODE>&amp;#xD;</CODE>)</LI>
     * </UL>
     *
     * @param name
     * @param value
     * @throws IOException
     */
    private void outputAttrToWriter(String name, String value) throws IOException {
        this.writer.write(" ");
        this.writer.write(name);
        this.writer.write("=\"");

        int length = value.length();

        for (int i = 0; i < length; i++) {
            char c = value.charAt(i);

            switch (c) {

            case '&':
                this.writer.write("&amp;amp;");
                break;

            case '<':
                this.writer.write("&amp;lt;");
                break;

            case '"':
                this.writer.write("&amp;quot;");
                break;

            case 0x09: // '\t'
                this.writer.write("&amp;#x9;");
                break;

            case 0x0A: // '\n'
                this.writer.write("&amp;#xA;");
                break;

            case 0x0D: // '\r'
                this.writer.write("&amp;#xD;");
                break;

            default:
                this.writer.write(c);
                break;
            }
        }

        this.writer.write("\"");
    }

    /**
     * Normalizes a {@link org.w3c.dom.Comment} value
     *
     * @param currentPI
     * @throws IOException
     */
    private void outputPItoWriter(ProcessingInstruction currentPI) throws IOException {

        if (currentPI == null) {
            return;
        }

        this.writer.write("&lt;?");

        String target = currentPI.getTarget();
        int length = target.length();

        for (int i = 0; i < length; i++) {
            char c = target.charAt(i);

            switch (c) {

            case 0x0D:
                this.writer.write("&amp;#xD;");
                break;

            case ' ':
                this.writer.write("&middot;");
                break;

            case '\n':
                this.writer.write("&para;\n");
                break;

            default:
                this.writer.write(c);
                break;
            }
        }

        String data = currentPI.getData();

        length = data.length();

        if (length > 0) {
            this.writer.write(" ");

            for (int i = 0; i < length; i++) {
                char c = data.charAt(i);

                if (c == 0x0D) {
                    this.writer.write("&amp;#xD;");
                } else {
                    this.writer.write(c);
                }
            }
        }

        this.writer.write("?&gt;");
    }

    /**
     * Method outputCommentToWriter
     *
     * @param currentComment
     * @throws IOException
     */
    private void outputCommentToWriter(Comment currentComment) throws IOException {

        if (currentComment == null) {
            return;
        }

        this.writer.write("&lt;!--");

        String data = currentComment.getData();
        int length = data.length();

        for (int i = 0; i < length; i++) {
            char c = data.charAt(i);

            switch (c) {

            case 0x0D:
                this.writer.write("&amp;#xD;");
                break;

            case ' ':
                this.writer.write("&middot;");
                break;

            case '\n':
                this.writer.write("&para;\n");
                break;

            default:
                this.writer.write(c);
                break;
            }
        }

        this.writer.write("--&gt;");
    }

    /**
     * Method outputTextToWriter
     *
     * @param text
     * @throws IOException
     */
    private void outputTextToWriter(String text) throws IOException {
        if (text == null) {
            return;
        }

        int length = text.length();

        for (int i = 0; i < length; i++) {
            char c = text.charAt(i);

            switch (c) {

            case '&':
                this.writer.write("&amp;amp;");
                break;

            case '<':
                this.writer.write("&amp;lt;");
                break;

            case '>':
                this.writer.write("&amp;gt;");
                break;

            case 0xD:
                this.writer.write("&amp;#xD;");
                break;

            case ' ':
                this.writer.write("&middot;");
                break;

            case '\n':
                this.writer.write("&para;\n");
                break;

            default:
                this.writer.write(c);
                break;
            }
        }
    }
}
