/*
 * 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 freemarker.ext.dom;

import java.util.Iterator;
import java.util.LinkedHashMap;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import freemarker.core.BugException;
import freemarker.core.Environment;
import freemarker.template.Template;
import freemarker.template.utility.StringUtil;

class NodeOutputter {
    
    private Element contextNode;
    private Environment env;
    private String defaultNS;
    private boolean hasDefaultNS;
    private boolean explicitDefaultNSPrefix;
    private LinkedHashMap<String, String> namespacesToPrefixLookup = new LinkedHashMap<>();
    private String namespaceDecl;
    int nextGeneratedPrefixNumber = 1;
    
    NodeOutputter(Node node) {
        if (node instanceof Element) {
            setContext((Element) node);
        } else if (node instanceof Attr) {
            setContext(((Attr) node).getOwnerElement());
        } else if (node instanceof Document) {
            setContext(((Document) node).getDocumentElement());
        }
    }
    
    private void setContext(Element contextNode) {
        this.contextNode = contextNode;
        this.env = Environment.getCurrentEnvironment();
        this.defaultNS = env.getDefaultNS();
        this.hasDefaultNS = defaultNS != null && defaultNS.length() > 0;
        namespacesToPrefixLookup.put(null, "");
        namespacesToPrefixLookup.put("", "");
        buildPrefixLookup(contextNode);
        if (!explicitDefaultNSPrefix && hasDefaultNS) {
            namespacesToPrefixLookup.put(defaultNS, "");
        }
        constructNamespaceDecl();
    }
    
    private void buildPrefixLookup(Node n) {
        String nsURI = n.getNamespaceURI();
        if (nsURI != null && nsURI.length() > 0) {
            String prefix = env.getPrefixForNamespace(nsURI);
            if (prefix == null) {
                prefix = namespacesToPrefixLookup.get(nsURI);
                if (prefix == null) {
                    // Assign a generated prefix:
                    do {
                        prefix = StringUtil.toLowerABC(nextGeneratedPrefixNumber++);
                    } while (env.getNamespaceForPrefix(prefix) != null);
                }
            }
            namespacesToPrefixLookup.put(nsURI, prefix);
        } else if (hasDefaultNS && n.getNodeType() == Node.ELEMENT_NODE) {
            namespacesToPrefixLookup.put(defaultNS, Template.DEFAULT_NAMESPACE_PREFIX); 
            explicitDefaultNSPrefix = true;
        } else if (n.getNodeType() == Node.ATTRIBUTE_NODE && hasDefaultNS && defaultNS.equals(nsURI)) {
            namespacesToPrefixLookup.put(defaultNS, Template.DEFAULT_NAMESPACE_PREFIX); 
            explicitDefaultNSPrefix = true;
        }
        NodeList childNodes = n.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            buildPrefixLookup(childNodes.item(i));
        }
    }
    
    private void constructNamespaceDecl() {
        StringBuilder buf = new StringBuilder();
        if (explicitDefaultNSPrefix) {
            buf.append(" xmlns=\"");
            buf.append(defaultNS);
            buf.append("\"");
        }
        for (Iterator<String> it = namespacesToPrefixLookup.keySet().iterator(); it.hasNext(); ) {
            String nsURI = it.next();
            if (nsURI == null || nsURI.length() == 0) {
                continue;
            }
            String prefix = namespacesToPrefixLookup.get(nsURI);
            if (prefix == null) {
                throw new BugException("No xmlns prefix was associated to URI: " + nsURI);
            }
            buf.append(" xmlns");
            if (prefix.length() > 0) {
                buf.append(":");
                buf.append(prefix);
            }
            buf.append("=\"");
            buf.append(nsURI);
            buf.append("\"");
        }
        this.namespaceDecl = buf.toString();
    }
    
    private void outputQualifiedName(Node n, StringBuilder buf) {
        String nsURI = n.getNamespaceURI();
        if (nsURI == null || nsURI.length() == 0) {
            buf.append(n.getNodeName());
        } else {
            String prefix = namespacesToPrefixLookup.get(nsURI);
            if (prefix == null) {
                //REVISIT!
                buf.append(n.getNodeName());
            } else {
                if (prefix.length() > 0) {
                    buf.append(prefix);
                    buf.append(':');
                }
                buf.append(n.getLocalName());
            }
        }
    }
    
    void outputContent(Node n, StringBuilder buf) {
        switch(n.getNodeType()) {
            case Node.ATTRIBUTE_NODE: {
                if (((Attr) n).getSpecified()) {
                    buf.append(' ');
                    outputQualifiedName(n, buf);
                    buf.append("=\"")
                       .append(StringUtil.XMLEncQAttr(n.getNodeValue()))
                       .append('"');
                }
                break;
            }
            case Node.COMMENT_NODE: {
                buf.append("<!--").append(n.getNodeValue()).append("-->");
                break;
            }
            case Node.DOCUMENT_NODE: {
                outputContent(n.getChildNodes(), buf);
                break;
            }
            case Node.DOCUMENT_TYPE_NODE: {
                buf.append("<!DOCTYPE ").append(n.getNodeName());
                DocumentType dt = (DocumentType) n;
                if (dt.getPublicId() != null) {
                    buf.append(" PUBLIC \"").append(dt.getPublicId()).append('"');
                }
                if (dt.getSystemId() != null) {
                    buf.append(" \"").append(dt.getSystemId()).append('"');
                }
                if (dt.getInternalSubset() != null) {
                    buf.append(" [").append(dt.getInternalSubset()).append(']');
                }
                buf.append('>');
                break;
            }
            case Node.ELEMENT_NODE: {
                buf.append('<');
                outputQualifiedName(n, buf);
                if (n == contextNode) {
                    buf.append(namespaceDecl);
                }
                outputContent(n.getAttributes(), buf);
                NodeList children = n.getChildNodes();
                if (children.getLength() == 0) {
                    buf.append(" />");
                } else {
                    buf.append('>');
                    outputContent(n.getChildNodes(), buf);
                    buf.append("</");
                    outputQualifiedName(n, buf);
                    buf.append('>');
                }
                break;
            }
            case Node.ENTITY_NODE: {
                outputContent(n.getChildNodes(), buf);
                break;
            }
            case Node.ENTITY_REFERENCE_NODE: {
                buf.append('&').append(n.getNodeName()).append(';');
                break;
            }
            case Node.PROCESSING_INSTRUCTION_NODE: {
                buf.append("<?").append(n.getNodeName()).append(' ').append(n.getNodeValue()).append("?>");
                break;
            }
            /*            
                        case Node.CDATA_SECTION_NODE: {
                            buf.append("<![CDATA[").append(n.getNodeValue()).append("]]>");
                            break;
                        }*/
            case Node.CDATA_SECTION_NODE:
            case Node.TEXT_NODE: {
                buf.append(StringUtil.XMLEncNQG(n.getNodeValue()));
                break;
            }
        }
    }

    void outputContent(NodeList nodes, StringBuilder buf) {
        for (int i = 0; i < nodes.getLength(); ++i) {
            outputContent(nodes.item(i), buf);
        }
    }
    
    void outputContent(NamedNodeMap nodes, StringBuilder buf) {
        for (int i = 0; i < nodes.getLength(); ++i) {
            Node n = nodes.item(i);
            if (n.getNodeType() != Node.ATTRIBUTE_NODE 
                || (!n.getNodeName().startsWith("xmlns:") && !n.getNodeName().equals("xmlns"))) { 
                outputContent(n, buf);
            }
        }
    }
    
    String getOpeningTag(Element element) {
        StringBuilder buf = new StringBuilder();
        buf.append('<');
        outputQualifiedName(element, buf);
        buf.append(namespaceDecl);
        outputContent(element.getAttributes(), buf);
        buf.append('>');
        return buf.toString();
    }
    
    String getClosingTag(Element element) {
        StringBuilder buf = new StringBuilder();
        buf.append("</");
        outputQualifiedName(element, buf);
        buf.append('>');
        return buf.toString();
    }
}
