//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.xml;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Stack;
import java.util.StringTokenizer;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/*--------------------------------------------------------------*/
/**
 * XML Parser wrapper. This class wraps any standard JAXP1.1 parser with convieniant error and
 * entity handlers and a mini dom-like document tree.
 * <p>
 * By default, the parser is created as a validating parser only if xerces is present. This can be
 * configured by setting the "org.eclipse.jetty.xml.XmlParser.Validating" system property.
 */
public class XmlParser
{
    private static final Logger LOG = Log.getLogger(XmlParser.class);

    private Map<String,URL> _redirectMap = new HashMap<String,URL>();
    private SAXParser _parser;
    private Map<String,ContentHandler> _observerMap;
    private Stack<ContentHandler> _observers = new Stack<ContentHandler>();
    private String _xpath;
    private Object _xpaths;
    private String _dtd;

    /* ------------------------------------------------------------ */
    /**
     * Construct
     */
    public XmlParser()
    {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        boolean validating_dft = factory.getClass().toString().startsWith("org.apache.xerces.");
        String validating_prop = System.getProperty("org.eclipse.jetty.xml.XmlParser.Validating", validating_dft ? "true" : "false");
        boolean validating = Boolean.valueOf(validating_prop).booleanValue();
        setValidating(validating);
    }

    /* ------------------------------------------------------------ */
    public XmlParser(boolean validating)
    {
        setValidating(validating);
    }

    /* ------------------------------------------------------------ */
    public void setValidating(boolean validating)
    {
        try
        {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setValidating(validating);
            _parser = factory.newSAXParser();

            try
            {
                if (validating)
                    _parser.getXMLReader().setFeature("http://apache.org/xml/features/validation/schema", validating);
            }
            catch (Exception e)
            {
                if (validating)
                    LOG.warn("Schema validation may not be supported: ", e);
                else
                    LOG.ignore(e);
            }

            _parser.getXMLReader().setFeature("http://xml.org/sax/features/validation", validating);
            _parser.getXMLReader().setFeature("http://xml.org/sax/features/namespaces", true);
            _parser.getXMLReader().setFeature("http://xml.org/sax/features/namespace-prefixes", false);
            try
            {
                if (validating)
                    _parser.getXMLReader().setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", validating);
            }
            catch (Exception e)
            {
                LOG.warn(e.getMessage());
            }
        }
        catch (Exception e)
        {
            LOG.warn(Log.EXCEPTION, e);
            throw new Error(e.toString());
        }
    }

    /* ------------------------------------------------------------ */
    public boolean isValidating()
    {
        return _parser.isValidating();
    }
    
    /* ------------------------------------------------------------ */
    public synchronized void redirectEntity(String name, URL entity)
    {
        if (entity != null)
            _redirectMap.put(name, entity);
    }

    /* ------------------------------------------------------------ */
    /**
     *
     * @return Returns the xpath.
     */
    public String getXpath()
    {
        return _xpath;
    }

    /* ------------------------------------------------------------ */
    /**
     * Set an XPath A very simple subset of xpath is supported to select a partial tree. Currently
     * only path like "/node1/nodeA | /node1/nodeB" are supported.
     *
     * @param xpath The xpath to set.
     */
    public void setXpath(String xpath)
    {
        _xpath = xpath;
        StringTokenizer tok = new StringTokenizer(xpath, "| ");
        while (tok.hasMoreTokens())
            _xpaths = LazyList.add(_xpaths, tok.nextToken());
    }

    /* ------------------------------------------------------------ */
    public String getDTD()
    {
        return _dtd;
    }

    /* ------------------------------------------------------------ */
    /**
     * Add a ContentHandler. Add an additional _content handler that is triggered on a tag name. SAX
     * events are passed to the ContentHandler provided from a matching start element to the
     * corresponding end element. Only a single _content handler can be registered against each tag.
     *
     * @param trigger Tag local or q name.
     * @param observer SAX ContentHandler
     */
    public synchronized void addContentHandler(String trigger, ContentHandler observer)
    {
        if (_observerMap == null)
            _observerMap = new HashMap<>();
        _observerMap.put(trigger, observer);
    }

    /* ------------------------------------------------------------ */
    public synchronized Node parse(InputSource source) throws IOException, SAXException
    {
        _dtd=null;
        Handler handler = new Handler();
        XMLReader reader = _parser.getXMLReader();
        reader.setContentHandler(handler);
        reader.setErrorHandler(handler);
        reader.setEntityResolver(handler);
        if (LOG.isDebugEnabled())
            LOG.debug("parsing: sid=" + source.getSystemId() + ",pid=" + source.getPublicId());
        _parser.parse(source, handler);
        if (handler._error != null)
            throw handler._error;
        Node doc = (Node) handler._top.get(0);
        handler.clear();
        return doc;
    }

    /* ------------------------------------------------------------ */
    /**
     * Parse String URL.
     * @param url the url to the xml to parse
     * @return the root node of the xml
     * @throws IOException if unable to load the xml
     * @throws SAXException if unable to parse the xml
     */
    public synchronized Node parse(String url) throws IOException, SAXException
    {
        if (LOG.isDebugEnabled())
            LOG.debug("parse: " + url);
        return parse(new InputSource(url));
    }

    /* ------------------------------------------------------------ */
    /**
     * Parse File.
     * @param file the file to the xml to parse 
     * @return the root node of the xml
     * @throws IOException if unable to load the xml
     * @throws SAXException if unable to parse the xml
     */
    public synchronized Node parse(File file) throws IOException, SAXException
    {
        if (LOG.isDebugEnabled())
            LOG.debug("parse: " + file);
        return parse(new InputSource(Resource.toURL(file).toString()));
    }

    /* ------------------------------------------------------------ */
    /**
     * Parse InputStream.
     * @param in the input stream of the xml to parse
     * @return the root node of the xml
     * @throws IOException if unable to load the xml
     * @throws SAXException if unable to parse the xml
     */
    public synchronized Node parse(InputStream in) throws IOException, SAXException
    {
        _dtd=null;
        Handler handler = new Handler();
        XMLReader reader = _parser.getXMLReader();
        reader.setContentHandler(handler);
        reader.setErrorHandler(handler);
        reader.setEntityResolver(handler);
        _parser.parse(new InputSource(in), handler);
        if (handler._error != null)
            throw handler._error;
        Node doc = (Node) handler._top.get(0);
        handler.clear();
        return doc;
    }


    /* ------------------------------------------------------------ */
    protected InputSource resolveEntity(String pid, String sid)
    {
        if (LOG.isDebugEnabled())
            LOG.debug("resolveEntity(" + pid + ", " + sid + ")");

        if (sid!=null && sid.endsWith(".dtd"))
            _dtd=sid;

        URL entity = null;
        if (pid != null)
            entity = (URL) _redirectMap.get(pid);
        if (entity == null)
            entity = (URL) _redirectMap.get(sid);
        if (entity == null)
        {
            String dtd = sid;
            if (dtd.lastIndexOf('/') >= 0)
                dtd = dtd.substring(dtd.lastIndexOf('/') + 1);

            if (LOG.isDebugEnabled())
                LOG.debug("Can't exact match entity in redirect map, trying " + dtd);
            entity = (URL) _redirectMap.get(dtd);
        }

        if (entity != null)
        {
            try
            {
                InputStream in = entity.openStream();
                if (LOG.isDebugEnabled())
                    LOG.debug("Redirected entity " + sid + " --> " + entity);
                InputSource is = new InputSource(in);
                is.setSystemId(sid);
                return is;
            }
            catch (IOException e)
            {
                LOG.ignore(e);
            }
        }
        return null;
    }
    
    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    private class NoopHandler extends DefaultHandler
    {
        Handler _next;
        int _depth;

        NoopHandler(Handler next)
        {
            this._next = next;
        }

        /* ------------------------------------------------------------ */
        public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException
        {
            _depth++;
        }

        /* ------------------------------------------------------------ */
        public void endElement(String uri, String localName, String qName) throws SAXException
        {
            if (_depth == 0)
                _parser.getXMLReader().setContentHandler(_next);
            else
                _depth--;
        }
    }

    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    private class Handler extends DefaultHandler
    {
        Node _top = new Node(null, null, null);
        SAXParseException _error;
        private Node _context = _top;
        private NoopHandler _noop;

        Handler()
        {
            _noop = new NoopHandler(this);
        }

        /* ------------------------------------------------------------ */
        void clear()
        {
            _top = null;
            _error = null;
            _context = null;
        }

        /* ------------------------------------------------------------ */
        public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException
        {
            String name = null;
            if (_parser.isNamespaceAware())
                name = localName;

            if (name == null || "".equals(name))
                name = qName;

            Node node = new Node(_context, name, attrs);


            // check if the node matches any xpaths set?
            if (_xpaths != null)
            {
                String path = node.getPath();
                boolean match = false;
                for (int i = LazyList.size(_xpaths); !match && i-- > 0;)
                {
                    String xpath = (String) LazyList.get(_xpaths, i);

                    match = path.equals(xpath) || xpath.startsWith(path) && xpath.length() > path.length() && xpath.charAt(path.length()) == '/';
                }

                if (match)
                {
                    _context.add(node);
                    _context = node;
                }
                else
                {
                    _parser.getXMLReader().setContentHandler(_noop);
                }
            }
            else
            {
                _context.add(node);
                _context = node;
            }

            ContentHandler observer = null;
            if (_observerMap != null)
                observer = (ContentHandler) _observerMap.get(name);
            _observers.push(observer);

            for (int i = 0; i < _observers.size(); i++)
                if (_observers.get(i) != null)
                    ((ContentHandler) _observers.get(i)).startElement(uri, localName, qName, attrs);
        }

        /* ------------------------------------------------------------ */
        public void endElement(String uri, String localName, String qName) throws SAXException
        {
            _context = _context._parent;
            for (int i = 0; i < _observers.size(); i++)
                if (_observers.get(i) != null)
                    ((ContentHandler) _observers.get(i)).endElement(uri, localName, qName);
            _observers.pop();
        }

        /* ------------------------------------------------------------ */
        public void ignorableWhitespace(char buf[], int offset, int len) throws SAXException
        {
            for (int i = 0; i < _observers.size(); i++)
                if (_observers.get(i) != null)
                    ((ContentHandler) _observers.get(i)).ignorableWhitespace(buf, offset, len);
        }

        /* ------------------------------------------------------------ */
        public void characters(char buf[], int offset, int len) throws SAXException
        {
            _context.add(new String(buf, offset, len));
            for (int i = 0; i < _observers.size(); i++)
                if (_observers.get(i) != null)
                    ((ContentHandler) _observers.get(i)).characters(buf, offset, len);
        }

        /* ------------------------------------------------------------ */
        public void warning(SAXParseException ex)
        {
            LOG.debug(Log.EXCEPTION, ex);
            LOG.warn("WARNING@" + getLocationString(ex) + " : " + ex.toString());
        }

        /* ------------------------------------------------------------ */
        public void error(SAXParseException ex) throws SAXException
        {
            // Save error and continue to report other errors
            if (_error == null)
                _error = ex;
            LOG.debug(Log.EXCEPTION, ex);
            LOG.warn("ERROR@" + getLocationString(ex) + " : " + ex.toString());
        }

        /* ------------------------------------------------------------ */
        public void fatalError(SAXParseException ex) throws SAXException
        {
            _error = ex;
            LOG.debug(Log.EXCEPTION, ex);
            LOG.warn("FATAL@" + getLocationString(ex) + " : " + ex.toString());
            throw ex;
        }

        /* ------------------------------------------------------------ */
        private String getLocationString(SAXParseException ex)
        {
            return ex.getSystemId() + " line:" + ex.getLineNumber() + " col:" + ex.getColumnNumber();
        }

        /* ------------------------------------------------------------ */
        public InputSource resolveEntity(String pid, String sid)
        {
            return XmlParser.this.resolveEntity(pid,sid);
        }
    }

    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    /**
     * XML Attribute.
     */
    public static class Attribute
    {
        private String _name;
        private String _value;

        Attribute(String n, String v)
        {
            _name = n;
            _value = v;
        }

        public String getName()
        {
            return _name;
        }

        public String getValue()
        {
            return _value;
        }
    }

    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    /**
     * XML Node. Represents an XML element with optional attributes and ordered content.
     */
    public static class Node extends AbstractList<Object>
    {
        Node _parent;
        private ArrayList<Object> _list;
        private String _tag;
        private Attribute[] _attrs;
        private boolean _lastString = false;
        private String _path;

        /* ------------------------------------------------------------ */
        Node(Node parent, String tag, Attributes attrs)
        {
            _parent = parent;
            _tag = tag;

            if (attrs != null)
            {
                _attrs = new Attribute[attrs.getLength()];
                for (int i = 0; i < attrs.getLength(); i++)
                {
                    String name = attrs.getLocalName(i);
                    if (name == null || name.equals(""))
                        name = attrs.getQName(i);
                    _attrs[i] = new Attribute(name, attrs.getValue(i));
                }
            }
        }

        /* ------------------------------------------------------------ */
        public Node getParent()
        {
            return _parent;
        }

        /* ------------------------------------------------------------ */
        public String getTag()
        {
            return _tag;
        }

        /* ------------------------------------------------------------ */
        public String getPath()
        {
            if (_path == null)
            {
                if (getParent() != null && getParent().getTag() != null)
                    _path = getParent().getPath() + "/" + _tag;
                else
                    _path = "/" + _tag;
            }
            return _path;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get an array of element attributes.
         * @return the attributes
         */
        public Attribute[] getAttributes()
        {
            return _attrs;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get an element attribute.
         * 
         * @param name the name of the attribute 
         * @return attribute or null.
         */
        public String getAttribute(String name)
        {
            return getAttribute(name, null);
        }

        /* ------------------------------------------------------------ */
        /**
         * Get an element attribute.
         * 
         * @param name the name of the element 
         * @param dft the default value
         * @return attribute or null.
         */
        public String getAttribute(String name, String dft)
        {
            if (_attrs == null || name == null)
                return dft;
            for (int i = 0; i < _attrs.length; i++)
                if (name.equals(_attrs[i].getName()))
                    return _attrs[i].getValue();
            return dft;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get the number of children nodes.
         */
        public int size()
        {
            if (_list != null)
                return _list.size();
            return 0;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get the ith child node or content.
         *
         * @return Node or String.
         */
        public Object get(int i)
        {
            if (_list != null)
                return _list.get(i);
            return null;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get the first child node with the tag.
         *
         * @param tag the name of the tag
         * @return Node or null.
         */
        public Node get(String tag)
        {
            if (_list != null)
            {
                for (int i = 0; i < _list.size(); i++)
                {
                    Object o = _list.get(i);
                    if (o instanceof Node)
                    {
                        Node n = (Node) o;
                        if (tag.equals(n._tag))
                            return n;
                    }
                }
            }
            return null;
        }

        /* ------------------------------------------------------------ */
        @Override
        public void add(int i, Object o)
        {
            if (_list == null)
                _list = new ArrayList<Object>();
            if (o instanceof String)
            {
                if (_lastString)
                {
                    int last = _list.size() - 1;
                    _list.set(last, (String) _list.get(last) + o);
                }
                else
                    _list.add(i, o);
                _lastString = true;
            }
            else
            {
                _lastString = false;
                _list.add(i, o);
            }
        }

        /* ------------------------------------------------------------ */
        public void clear()
        {
            if (_list != null)
                _list.clear();
            _list = null;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get a tag as a string.
         *
         * @param tag The tag to get
         * @param tags IF true, tags are included in the value.
         * @param trim If true, trim the value.
         * @return results of get(tag).toString(tags).
         */
        public String getString(String tag, boolean tags, boolean trim)
        {
            Node node = get(tag);
            if (node == null)
                return null;
            String s = node.toString(tags);
            if (s != null && trim)
                s = s.trim();
            return s;
        }

        /* ------------------------------------------------------------ */
        public synchronized String toString()
        {
            return toString(true);
        }

        /* ------------------------------------------------------------ */
        /**
         * Convert to a string.
         *
         * @param tag If false, only _content is shown.
         * @return the string value
         */
        public synchronized String toString(boolean tag)
        {
            StringBuilder buf = new StringBuilder();
            toString(buf, tag);
            return buf.toString();
        }

        /* ------------------------------------------------------------ */
        /**
         * Convert to a string.
         *
         * @param tag If false, only _content is shown.
         * @param trim true to trim the content
         * @return the trimmed content
         */
        public synchronized String toString(boolean tag, boolean trim)
        {
            String s = toString(tag);
            if (s != null && trim)
                s = s.trim();
            return s;
        }

        /* ------------------------------------------------------------ */
        private synchronized void toString(StringBuilder buf, boolean tag)
        {
            if (tag)
            {
                buf.append("<");
                buf.append(_tag);

                if (_attrs != null)
                {
                    for (int i = 0; i < _attrs.length; i++)
                    {
                        buf.append(' ');
                        buf.append(_attrs[i].getName());
                        buf.append("=\"");
                        buf.append(_attrs[i].getValue());
                        buf.append("\"");
                    }
                }
            }

            if (_list != null)
            {
                if (tag)
                    buf.append(">");
                for (int i = 0; i < _list.size(); i++)
                {
                    Object o = _list.get(i);
                    if (o == null)
                        continue;
                    if (o instanceof Node)
                        ((Node) o).toString(buf, tag);
                    else
                        buf.append(o.toString());
                }
                if (tag)
                {
                    buf.append("</");
                    buf.append(_tag);
                    buf.append(">");
                }
            }
            else if (tag)
                buf.append("/>");
        }

        /* ------------------------------------------------------------ */
        /**
         * Iterator over named child nodes.
         *
         * @param tag The tag of the nodes.
         * @return Iterator over all child nodes with the specified tag.
         */
        public Iterator<Node> iterator(final String tag)
        {
            return new Iterator<Node>()
            {
                int c = 0;
                Node _node;

                /* -------------------------------------------------- */
                public boolean hasNext()
                {
                    if (_node != null)
                        return true;
                    while (_list != null && c < _list.size())
                    {
                        Object o = _list.get(c);
                        if (o instanceof Node)
                        {
                            Node n = (Node) o;
                            if (tag.equals(n._tag))
                            {
                                _node = n;
                                return true;
                            }
                        }
                        c++;
                    }
                    return false;
                }

                /* -------------------------------------------------- */
                public Node next()
                {
                    try
                    {
                        if (hasNext())
                            return _node;
                        throw new NoSuchElementException();
                    }
                    finally
                    {
                        _node = null;
                        c++;
                    }
                }

                /* -------------------------------------------------- */
                public void remove()
                {
                    throw new UnsupportedOperationException("Not supported");
                }
            };
        }
    }
}
