/*
 * 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.IOException;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;

import org.jaxen.Context;
import org.jaxen.NamespaceContext;
import org.jaxen.jdom.JDOMXPath;
import org.jdom.Attribute;
import org.jdom.CDATA;
import org.jdom.Comment;
import org.jdom.DocType;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.EntityRef;
import org.jdom.Namespace;
import org.jdom.ProcessingInstruction;
import org.jdom.Text;
import org.jdom.output.XMLOutputter;

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 _JdomNavigator extends Navigator {
    private static final XMLOutputter OUTPUT = new XMLOutputter();
    
    public _JdomNavigator() {
    } 

    @Override
    void getAsString(Object node, StringWriter sw)
    throws TemplateModelException {
        try {
            if (node instanceof Element) {
                OUTPUT.output((Element) node, sw);
            } else if (node instanceof Attribute) {
                Attribute attribute = (Attribute) node;
                sw.write(" ");
                sw.write(attribute.getQualifiedName());
                sw.write("=\"");
                sw.write(OUTPUT.escapeAttributeEntities(attribute.getValue()));
                sw.write("\"");
            } else if (node instanceof Text) {
                OUTPUT.output((Text) node, sw);
            } else if (node instanceof Document) {
                OUTPUT.output((Document) node, sw);
            } else if (node instanceof ProcessingInstruction) {
                OUTPUT.output((ProcessingInstruction) node, sw);
            } else if (node instanceof Comment) {
                OUTPUT.output((Comment) node, sw);
            } else if (node instanceof CDATA) {
                OUTPUT.output((CDATA) node, sw);
            } else if (node instanceof DocType) {
                OUTPUT.output((DocType) node, sw);
            } else if (node instanceof EntityRef) {
                OUTPUT.output((EntityRef) node, sw);
            } else {
                throw new TemplateModelException(node.getClass().getName() + " is not a core JDOM class");
            }
        } catch (IOException e) {
            throw new TemplateModelException(e);
        }
    }

    @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.getChildren());
            } else {
                result.addAll(e.getChildren(localName, Namespace.getNamespace("", 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.getAttributes());
            } else {
                Attribute attr = e.getAttribute(localName, Namespace.getNamespace("", namespaceUri)); 
                if (attr != null) {
                    result.add(attr);
                } 
            }
        } else if (node instanceof ProcessingInstruction) {
            ProcessingInstruction pi = (ProcessingInstruction) node;
            if ("target".equals(localName)) {
                result.add(new Attribute("target", pi.getTarget()));
            } else if ("data".equals(localName)) {
                result.add(new Attribute("data", pi.getData()));
            } else {
                result.add(new Attribute(localName, pi.getValue(localName)));
            }
        } else if (node instanceof DocType) {
            DocType doctype = (DocType) node;
            if ("publicId".equals(localName)) {
                result.add(new Attribute("publicId", doctype.getPublicID()));
            } else if ("systemId".equals(localName)) {
                result.add(new Attribute("systemId", doctype.getSystemID()));
            } else if ("elementName".equals(localName)) {
                result.add(new Attribute("elementName", doctype.getElementName()));
            }
        } 
    }

    @Override
    void getDescendants(Object node, List result) {
        if (node instanceof Document) {
            Element root = ((Document) node).getRootElement();
            result.add(root);
            getDescendants(root, result);
        } else if (node instanceof Element) {
            getDescendants((Element) node, result);
        }
    }
    
    private void getDescendants(Element node, List result) {
        for (Iterator iter = node.getChildren().iterator(); iter.hasNext(); ) {
            Element subnode = (Element) iter.next();
            result.add(subnode);
            getDescendants(subnode, result);
        }
    }

    @Override
    Object getParent(Object node) {
        if (node instanceof Element) {
            return((Element) node).getParent();
        }
        if (node instanceof Attribute) {
            return((Attribute) node).getParent();
        }
        if (node instanceof Text) {
            return((Text) node).getParent();
        }
        if (node instanceof ProcessingInstruction) {
            return((ProcessingInstruction) node).getParent();
        }
        if (node instanceof Comment) {
            return((Comment) node).getParent();
        }
        if (node instanceof EntityRef) {
            return((EntityRef) node).getParent();
        }
        return null;
    }

    @Override
    Object getDocument(Object node) {
        if (node instanceof Element) {
            return ((Element) node).getDocument();
        } else if (node instanceof Attribute) {
            Element parent = ((Attribute) node).getParent();
            return parent == null ? null : parent.getDocument();
        } else if (node instanceof Text) {
            Element parent = ((Text) node).getParent();
            return parent == null ? null : parent.getDocument();
        } else if (node instanceof Document)
            return node;
        else if (node instanceof ProcessingInstruction) {
            return ((ProcessingInstruction) node).getDocument();
        } else if (node instanceof EntityRef) {
            return ((EntityRef) node).getDocument();
        } else if (node instanceof Comment) {
            return ((Comment) node).getDocument();
        }
        return null;
    }

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

    @Override
    String getText(Object node) {
        if (node instanceof Element) {
            return ((Element) node).getTextTrim();
        }
        if (node instanceof Attribute) {
            return ((Attribute) node).getValue();
        }
        if (node instanceof CDATA) {
            return ((CDATA) node).getText();
        }
        if (node instanceof Comment) {
            return ((Comment) node).getText();
        }
        if (node instanceof ProcessingInstruction) {
            return ((ProcessingInstruction) node).getData();
        }
        return null;
    }

    @Override
    String getLocalName(Object node) {
        if (node instanceof Element) {
            return ((Element) node).getName();
        }
        if (node instanceof Attribute) {
            return ((Attribute) node).getName();
        }
        if (node instanceof EntityRef) {
            return ((EntityRef) node).getName();
        }
        if (node instanceof ProcessingInstruction) {
            return ((ProcessingInstruction) node).getTarget();
        }
        if (node instanceof DocType) {
            return ((DocType) node).getElementName();
        }
        return null;
    }

    @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) {
        if (node instanceof Attribute) {
            return "attribute";
        }
        if (node instanceof CDATA) {
            return "cdata";
        }
        if (node instanceof Comment) {
            return "comment";
        }
        if (node instanceof Document) {
            return "document";
        }
        if (node instanceof DocType) {
            return "documentType";
        }
        if (node instanceof Element) {
            return "element";
        }
        if (node instanceof EntityRef) {
            return "entityReference";
        }
        if (node instanceof Namespace) {
            return "namespace";
        }
        if (node instanceof ProcessingInstruction) {
            return "processingInstruction";
        }
        if (node instanceof Text) {
            return "text";
        }
        return "unknown";
    }

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

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

        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);
            }
        } 
    }
}
