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

import com.ibm.wsdl.Constants;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.axiom.util.base64.Base64Utils;
import org.w3c.dom.Attr;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLStreamException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Stack;


public class XMLUtils {
    public static final String charEncoding = "ISO-8859-1";
    private static final String saxParserFactoryProperty =
            "javax.xml.parsers.SAXParserFactory";

    private static DocumentBuilderFactory dbf = getDOMFactory();
    private static SAXParserFactory saxFactory;
    private static Stack saxParsers = new Stack();

    private static String empty = "";
    private static ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());

    static {
        // Initialize SAX Parser factory defaults
        initSAXFactory(null, true, false);
    }

    /**
     * Initializes the SAX parser factory.
     *
     * @param factoryClassName The (optional) class name of the desired
     *                         SAXParserFactory implementation. Will be
     *                         assigned to the system property
     *                         <b>javax.xml.parsers.SAXParserFactory</b>
     *                         unless this property is already set.
     *                         If <code>null</code>, leaves current setting
     *                         alone.
     * @param namespaceAware   true if we want a namespace-aware parser
     * @param validating       true if we want a validating parser
     */
    public static void initSAXFactory(String factoryClassName,
                                      boolean namespaceAware,
                                      boolean validating) {
        if (factoryClassName != null) {
            try {
                saxFactory = (SAXParserFactory) Loader.loadClass(factoryClassName).
                        newInstance();
                /*
                 * Set the system property only if it is not already set to
                 * avoid corrupting environments in which Axis is embedded.
                 */
                if (System.getProperty(saxParserFactoryProperty) == null) {
                    System.setProperty(saxParserFactoryProperty,
                                       factoryClassName);
                }
            } catch (Exception e) {
                saxFactory = SAXParserFactory.newInstance();
            }
        } else {
            saxFactory = SAXParserFactory.newInstance();
        }
        saxFactory.setNamespaceAware(namespaceAware);
        saxFactory.setValidating(validating);

        // Discard existing parsers
        saxParsers.clear();
    }

    private static DocumentBuilderFactory getDOMFactory() {
        DocumentBuilderFactory dbf;
        try {
            dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
        }
        catch (Exception e) {
            //log.error(Messages.getMessage("exception00"), e );
            dbf = null;
        }
        return (dbf);
    }

    private static boolean tryReset = true;

    /**
     * Returns a SAX parser for reuse.
     *
     * @param parser A SAX parser that is available for reuse
     */
    public static void releaseSAXParser(SAXParser parser) {
        if (!tryReset) {
            return;
        }

        //Free up possible ref. held by past contenthandler.
        try {
            XMLReader xmlReader = parser.getXMLReader();
            if (null != xmlReader) {
                synchronized (XMLUtils.class) {
                    saxParsers.push(parser);
                }
            } else {
                tryReset = false;
            }
        } catch (org.xml.sax.SAXException e) {
            tryReset = false;
        }
    }

    /**
     * Gets an empty new Document.
     *
     * @return Returns Document.
     * @throws ParserConfigurationException if construction problems occur
     */
    public static Document newDocument()
            throws ParserConfigurationException {
        synchronized (dbf) {
            return dbf.newDocumentBuilder().newDocument();
        }
    }

    /**
     * Gets a new Document read from the input source.
     *
     * @return Returns Document.
     * @throws ParserConfigurationException if construction problems occur
     * @throws SAXException                 if the document has xml sax problems
     * @throws IOException                  if i/o exceptions occur
     */
    public static Document newDocument(InputSource inp)
            throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilder db;
        synchronized (dbf) {
            try {
                db = dbf.newDocumentBuilder();
            } catch (Exception e){
                // Under some peculiar conditions (classloader issues), just scrap the old dbf, create a new one and try again.
                dbf = getDOMFactory();
                db = dbf.newDocumentBuilder();
            }
        }
        db.setEntityResolver(new DefaultEntityResolver());
        db.setErrorHandler(new ParserErrorHandler());
        return (db.parse(inp));
    }

    /**
     * Gets a new Document read from the input stream
     *
     * @return Returns Document.
     * @throws ParserConfigurationException if construction problems occur
     * @throws SAXException                 if the document has xml sax problems
     * @throws IOException                  if i/o exceptions occur
     */
    public static Document newDocument(InputStream inp)
            throws ParserConfigurationException, SAXException, IOException {
        return XMLUtils.newDocument(new InputSource(inp));
    }

    /**
     * Gets a new Document read from the indicated uri
     *
     * @return Returns Document.
     * @throws ParserConfigurationException if construction problems occur
     * @throws SAXException                 if the document has xml sax problems
     * @throws IOException                  if i/o exceptions occur
     */
    public static Document newDocument(String uri)
            throws ParserConfigurationException, SAXException, IOException {
        // call the authenticated version as there might be 
        // username/password info embeded in the uri.
        return XMLUtils.newDocument(uri, null, null);
    }

    /**
     * Creates a new document from the given URI. Uses the username and password
     * if the URI requires authentication.
     *
     * @param uri      the resource to get
     * @param username basic auth username
     * @param password basic auth password
     * @throws ParserConfigurationException if construction problems occur
     * @throws SAXException                 if the document has xml sax problems
     * @throws IOException                  if i/o exceptions occur
     */
    public static Document newDocument(String uri, String username, String password)
            throws ParserConfigurationException, SAXException, IOException {
        InputSource ins = XMLUtils.getInputSourceFromURI(uri, username, password);
        Document doc = XMLUtils.newDocument(ins);
        // Close the Stream
        if (ins.getByteStream() != null) {
            ins.getByteStream().close();
        } else if (ins.getCharacterStream() != null) {
            ins.getCharacterStream().close();
        }
        return doc;
    }


    public static String getPrefix(String uri, Node e) {
        while (e != null && (e.getNodeType() == Element.ELEMENT_NODE)) {
            NamedNodeMap attrs = e.getAttributes();
            for (int n = 0; n < attrs.getLength(); n++) {
                Attr a = (Attr) attrs.item(n);
                String name;
                if ((name = a.getName()).startsWith("xmlns:") &&
                        a.getNodeValue().equals(uri)) {
                    return name.substring(6);
                }
            }
            e = e.getParentNode();
        }
        return null;
    }

    public static String getNamespace(String prefix, Node e) {
        while (e != null && (e.getNodeType() == Node.ELEMENT_NODE)) {
            Attr attr =
                    ((Element) e).getAttributeNodeNS(Constants.NS_URI_XMLNS, prefix);
            if (attr != null) {
                return attr.getValue();
            }
            e = e.getParentNode();
        }
        return null;
    }

    /**
     * Returns a QName when passed a string like "foo:bar" by mapping
     * the "foo" prefix to a namespace in the context of the given Node.
     *
     * @return Returns a QName generated from the given string representation.
     */
    public static QName getQNameFromString(String str, Node e) {
        if (str == null || e == null) {
            return null;
        }

        int idx = str.indexOf(':');
        if (idx > -1) {
            String prefix = str.substring(0, idx);
            String ns = getNamespace(prefix, e);
            if (ns == null) {
                return null;
            }
            return new QName(ns, str.substring(idx + 1));
        } else {
            return new QName("", str);
        }
    }

    /**
     * Returns a string for a particular QName, mapping a new prefix
     * if necessary.
     */
    public static String getStringForQName(QName qname, Element e) {
        String uri = qname.getNamespaceURI();
        String prefix = getPrefix(uri, e);
        if (prefix == null) {
            int i = 1;
            prefix = "ns" + i;
            while (getNamespace(prefix, e) != null) {
                i++;
                prefix = "ns" + i;
            }
            e.setAttributeNS(Constants.NS_URI_XMLNS,
                             "xmlns:" + prefix, uri);
        }
        return prefix + ":" + qname.getLocalPart();
    }

    /**
     * Concatinates all the text and cdata node children of this elem and returns
     * the resulting text.
     * (by Matt Duftler)
     *
     * @param parentEl the element whose cdata/text node values are to
     *                 be combined.
     * @return Returns the concatinated string.
     */
    public static String getChildCharacterData(Element parentEl) {
        if (parentEl == null) {
            return null;
        }
        Node tempNode = parentEl.getFirstChild();
        StringBuffer strBuf = new StringBuffer();
        CharacterData charData;

        while (tempNode != null) {
            switch (tempNode.getNodeType()) {
                case Node.TEXT_NODE :
                case Node.CDATA_SECTION_NODE:
                    charData = (CharacterData) tempNode;
                    strBuf.append(charData.getData());
                    break;
            }
            tempNode = tempNode.getNextSibling();
        }
        return strBuf.toString();
    }

    public static class ParserErrorHandler implements ErrorHandler {
        /**
         * Returns a string describing parse exception details
         */
        private String getParseExceptionInfo(SAXParseException spe) {
            String systemId = spe.getSystemId();
            if (systemId == null) {
                systemId = "null";
            }
            return "URI=" + systemId +
                    " Line=" + spe.getLineNumber() +
                    ": " + spe.getMessage();
        }

        // The following methods are standard SAX ErrorHandler methods.
        // See SAX documentation for more info.

        public void warning(SAXParseException spe) throws SAXException {
        }

        public void error(SAXParseException spe) throws SAXException {
            String message = "Error: " + getParseExceptionInfo(spe);
            throw new SAXException(message);
        }

        public void fatalError(SAXParseException spe) throws SAXException {
            String message = "Fatal Error: " + getParseExceptionInfo(spe);
            throw new SAXException(message);
        }
    }


    /**
     * Utility to get the bytes uri.
     * Does NOT handle authenticated URLs,
     * use getInputSourceFromURI(uri, username, password)
     *
     * @param uri the resource to get
     */
    public static InputSource getInputSourceFromURI(String uri) {
        return new InputSource(uri);
    }


    /**
     * Utility to get the bytes at a protected uri
     * <p/>
     * Retrieves the URL if a username and password are provided.
     * The java.net.URL class does not do Basic Authentication, so we have to
     * do it manually in this routine.
     * <p/>
     * If no username is provided, creates an InputSource from the uri
     * and lets the InputSource go fetch the contents.
     *
     * @param uri      the resource to get
     * @param username basic auth username
     * @param password basic auth password
     */
    private static InputSource getInputSourceFromURI(String uri,
                                                     String username,
                                                     String password)
            throws IOException, ProtocolException, UnsupportedEncodingException {
        URL wsdlurl = null;
        try {
            wsdlurl = new URL(uri);
        } catch (MalformedURLException e) {
            // we can't process it, it might be a 'simple' foo.wsdl
            // let InputSource deal with it
            return new InputSource(uri);
        }

        // if no authentication, just let InputSource deal with it
        if (username == null && wsdlurl.getUserInfo() == null) {
            return new InputSource(uri);
        }

        // if this is not an HTTP{S} url, let InputSource deal with it
        if (!wsdlurl.getProtocol().startsWith("http")) {
            return new InputSource(uri);
        }

        URLConnection connection = wsdlurl.openConnection();
        // Does this work for https???
        if (!(connection instanceof HttpURLConnection)) {
            // can't do http with this URL, let InputSource deal with it
            return new InputSource(uri);
        }
        HttpURLConnection uconn = (HttpURLConnection) connection;
        String userinfo = wsdlurl.getUserInfo();
        uconn.setRequestMethod("GET");
        uconn.setAllowUserInteraction(false);
        uconn.setDefaultUseCaches(false);
        uconn.setDoInput(true);
        uconn.setDoOutput(false);
        uconn.setInstanceFollowRedirects(true);
        uconn.setUseCaches(false);

        // username/password info in the URL overrides passed in values 
        String auth = null;
        if (userinfo != null) {
            auth = userinfo;
        } else if (username != null) {
            auth = (password == null) ? username : username + ":" + password;
        }

        if (auth != null) {
            uconn.setRequestProperty("Authorization",
                                     "Basic " +
                                             base64encode(auth.getBytes(charEncoding)));
        }

        uconn.connect();

        return new InputSource(uconn.getInputStream());
    }

    public static String base64encode(byte[] bytes) {
        return Base64Utils.encode(bytes);
    }

    public static InputSource getEmptyInputSource() {
        return new InputSource(bais);
    }

    /**
     * Finds a Node with a given QNameb.
     *
     * @param node parent node
     * @param name QName of the child we need to find
     * @return Returns child node.
     */
    public static Node findNode(Node node, QName name) {
        if (name.getNamespaceURI().equals(node.getNamespaceURI()) &&
                name.getLocalPart().equals(node.getLocalName())) {
            return node;
        }
        NodeList children = node.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node ret = findNode(children.item(i), name);
            if (ret != null) {
                return ret;
            }
        }
        return null;
    }

    /**
     * Convert DOM Element into a fully built OMElement
     * @param element dom Element
     * @return OMElement
     * @throws Exception
     */
    public static OMElement toOM(Element element) throws Exception {
        OMXMLParserWrapper builder = OMXMLBuilderFactory.createOMBuilder(element, true);
        builder.detach();
        return builder.getDocumentElement();
    }

    /**
     * Converts a given OMElement to a DOM Element.
     *
     * @param element
     * @return Returns Element.
     * @throws Exception
     */
    public static Element toDOM(OMElement element) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        element.serialize(baos);
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        return factory.newDocumentBuilder().parse(bais).getDocumentElement();
    }


    /**
     * Converts a given inputstream to an OMNode
     * The reurned OMNode is fully built.
     *
     * @param inputStream
     * @return OMNode
     * @throws javax.xml.stream.XMLStreamException
     *
     */
    public static OMNode toOM(InputStream inputStream) throws XMLStreamException {
        return toOM(inputStream, true);
    }
    
    /**
     * Converts a given inputstream to an OMNode
     * The reurned OMNode is fully built if buildAll is true.
     * If buildAll is false, the caller is responsible for closing the parser.
     *
     * @param inputStream
     * @param buildAll
     * @return OMNode
     * @throws javax.xml.stream.XMLStreamException
     *
     */
    public static OMNode toOM(InputStream inputStream, boolean buildAll) throws XMLStreamException {
        OMXMLParserWrapper builder = OMXMLBuilderFactory.createOMBuilder(inputStream);
        OMNode omNode = builder.getDocumentElement();
        
        if (buildAll) {
            omNode.build();
            builder.close();
        }
        
        return omNode;
    }

    /**
     * Converts a given Reader to an OMNode.
     * The reurned OMNode is fully built.
     *
     * @param reader
     * @return
     * @throws XMLStreamException
     */
    public static OMNode toOM(Reader reader) throws XMLStreamException {
        return toOM(reader, true);
    }
    
    /**
     * Converts a given Reader to an OMNode.
     * The reurned OMNode is fully built if buildAll is true.
     * If buildAll is false, the caller is responsible for closing the parser.
     *
     * @param reader
     * @param buildAll
     * @return OMNode
     * @throws XMLStreamException
     */
    public static OMNode toOM(Reader reader, boolean buildAll) throws XMLStreamException {
        OMXMLParserWrapper builder = OMXMLBuilderFactory.createOMBuilder(reader);
        OMNode omNode = builder.getDocumentElement();
        
        if (buildAll) {
            omNode.build();
            builder.close();
        }
        
        return omNode;
    }
}
