/*
 * 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.xml;

import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Branch;
import org.dom4j.Document;
import org.dom4j.DocumentType;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.ProcessingInstruction;
import org.dom4j.tree.DefaultAttribute;
import org.jaxen.Context;
import org.jaxen.NamespaceContext;
import org.jaxen.dom4j.Dom4jXPath;

import freemarker.template.TemplateModelException;

/**
 * Don't use this class; it's only public to work around Google App Engine Java
 * compliance issues. FreeMarker developers only: treat this class as package-visible.
 */
public class _Dom4jNavigator extends Navigator {

    public _Dom4jNavigator() {
    } 

    @Override
    void getAsString(Object node, StringWriter sw) {
        sw.getBuffer().append(((Node) node).asXML());
    }

    @Override
    void getChildren(Object node, String localName, String namespaceUri, List result) {
        if (node instanceof Element) {
            Element e = (Element) node;
            if (localName == null) {
                result.addAll(e.elements());
            } else {
                result.addAll(e.elements(e.getQName().getDocumentFactory().createQName(localName, "", namespaceUri)));
            }
        } else if (node instanceof Document) {
            Element root = ((Document) node).getRootElement();
            if (localName == null || (equal(root.getName(), localName) && equal(root.getNamespaceURI(), namespaceUri))) {
                result.add(root);
            }
        }
    }
    
    @Override
    void getAttributes(Object node, String localName, String namespaceUri, List result) {
        if (node instanceof Element) {
            Element e = (Element) node;
            if (localName == null) {
                result.addAll(e.attributes());
            } else {
                Attribute attr = e.attribute(e.getQName().getDocumentFactory().createQName(localName, "", namespaceUri)); 
                if (attr != null) {
                    result.add(attr);
                }
            }
        } else if (node instanceof ProcessingInstruction) {
            ProcessingInstruction pi = (ProcessingInstruction) node;
            if ("target".equals(localName)) {
                result.add(new DefaultAttribute("target", pi.getTarget()));
            } else if ("data".equals(localName)) {
                result.add(new DefaultAttribute("data", pi.getText()));
            } else {
                result.add(new DefaultAttribute(localName, pi.getValue(localName)));
            }
        } else if (node instanceof DocumentType) {
            DocumentType doctype = (DocumentType) node;
            if ("publicId".equals(localName)) {
                result.add(new DefaultAttribute("publicId", doctype.getPublicID()));
            } else if ("systemId".equals(localName)) {
                result.add(new DefaultAttribute("systemId", doctype.getSystemID()));
            } else if ("elementName".equals(localName)) {
                result.add(new DefaultAttribute("elementName", doctype.getElementName()));
            }
        } 
    }

    @Override
    void getDescendants(Object node, List result) {
        if (node instanceof Branch) {
            getDescendants((Branch) node, result);
        }
    }
    
    private void getDescendants(Branch node, List result) {
        List content = node.content();
        for (Iterator iter = content.iterator(); iter.hasNext(); ) {
            Node subnode = (Node) iter.next();
            if (subnode instanceof Element) {
                result.add(subnode);
                getDescendants(subnode, result);
            }
        }
    }

    @Override
    Object getParent(Object node) {
        return ((Node) node).getParent();
    }

    @Override
    Object getDocument(Object node) {
        return ((Node) node).getDocument();
    }

    @Override
    Object getDocumentType(Object node) {
        return 
            node instanceof Document 
            ? ((Document) node).getDocType()
            : null; 
    }
    
    @Override
    void getContent(Object node, List result) {
        if (node instanceof Branch) {
            result.addAll(((Branch) node).content());
        }
    }

    @Override
    String getText(Object node) {
        return ((Node) node).getText();
    }

    @Override
    String getLocalName(Object node) {
        return ((Node) node).getName();
    }

    @Override
    String getNamespacePrefix(Object node) {
        if (node instanceof Element) {
            return ((Element) node).getNamespacePrefix();
        }
        if (node instanceof Attribute) {
            return ((Attribute) node).getNamespacePrefix();
        }
        return null;
    }

    @Override
    String getNamespaceUri(Object node) {
        if (node instanceof Element) {
            return ((Element) node).getNamespaceURI();
        }
        if (node instanceof Attribute) {
            return ((Attribute) node).getNamespaceURI();
        }
        return null;
    }

    @Override
    String getType(Object node) {
        switch(((Node) node).getNodeType()) {
            case Node.ATTRIBUTE_NODE: {
                return "attribute";
            }
            case Node.CDATA_SECTION_NODE: {
                return "cdata";
            }
            case Node.COMMENT_NODE: {
                return "comment";
            }
            case Node.DOCUMENT_NODE: {
                return "document";
            }
            case Node.DOCUMENT_TYPE_NODE: {
                return "documentType";
            }
            case Node.ELEMENT_NODE: {
                return "element";
            }
            case Node.ENTITY_REFERENCE_NODE: {
                return "entityReference";
            }
            case Node.NAMESPACE_NODE: {
                return "namespace";
            }
            case Node.PROCESSING_INSTRUCTION_NODE: {
                return "processingInstruction";
            }
            case Node.TEXT_NODE: {
                return "text";
            }
        }
        return "unknown";
    }

    @Override
    XPathEx createXPathEx(String xpathString) throws TemplateModelException {
        try {
            return new Dom4jXPathEx(xpathString);
        } catch (Exception e) {
            throw new TemplateModelException(e);
        }
    }

    private static final class Dom4jXPathEx
    extends
        Dom4jXPath
    implements
        XPathEx {
        Dom4jXPathEx(String path)
        throws Exception {
            super(path);
        }

        @Override
        public List selectNodes(Object object, NamespaceContext namespaces)
        throws TemplateModelException {
            Context context = getContext(object);
            context.getContextSupport().setNamespaceContext(namespaces);
            try {
                return selectNodesForContext(context);
            } catch (Exception e) {
                throw new TemplateModelException(e);
            }
        } 
    }
}
