/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.oxm.record;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.Unmarshaller;
import org.eclipse.persistence.internal.oxm.mappings.Login;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.record.namespaces.StackUnmarshalNamespaceResolver;
import org.eclipse.persistence.oxm.documentpreservation.DocumentPreservationPolicy;

import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
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.w3c.dom.Text;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.ext.Locator2;

/**
 *  INTERNAL:
 *  <p><b>Purpose:</b> An implementation of XMLReader for parsing DOM Nodes into SAX events.
 *  <p><b>Responsibilities:</b><ul>
 *  <li>Walk the DOM tree and report sax events to the provided content handler</li>
 *  <li>Report lexical events to the lexical handler if it's provided</li>
 *  <li>Listen for callbacks from the Mapping-Level framework to handle caching nodes for document preservation</li>
 *  </ul>
 *
 */
public class DOMReader extends XMLReaderAdapter {

    private Node currentNode;
    private DocumentPreservationPolicy docPresPolicy;

    public DOMReader() {
        super();
    }

    public DOMReader(Unmarshaller xmlUnmarshaller) {
        super(xmlUnmarshaller);
    }

    @Override
    public void parse(InputSource input) throws SAXException {
        if(input instanceof DOMInputSource) {
            Node node = ((DOMInputSource) input).getNode();
            if(contentHandler != null && contentHandler.getClass() == SAXUnmarshallerHandler.class){
                ((SAXUnmarshallerHandler)contentHandler).setUnmarshalNamespaceResolver(new StackUnmarshalNamespaceResolver());
            }
            parse(node);
        }
    }

    public void parse (Node node, String newURI, String newName) throws SAXException {
        if(null == contentHandler) {
            return;
        }
        Element rootNode = null;
        if(node.getNodeType() == Node.DOCUMENT_NODE) {
            rootNode = ((Document)node).getDocumentElement();
        }  else {
            rootNode = (Element)node;
        }
        if(rootNode == null) {
            return;
        }
        processParentNamespaces(rootNode);
        startDocument();
        setupLocator(rootNode.getOwnerDocument());

        reportElementEvents(rootNode, newURI, newName);


        endDocument();
    }

    public void parse (Node node) throws SAXException {
        parse(node, null, null);
    }

    /**
     * Process namespace declarations on parent elements if not the root.
     * For each parent node from current to root push each onto a stack,
     * then pop each off, calling startPrefixMapping for each XMLNS
     * attribute.  Using a stack ensures that the parent nodes are
     * processed top down.
     *
     */
    protected void processParentNamespaces(Element element) throws SAXException {
        Node parent = element.getParentNode();
        // If we're already at the root, do nothing
        if (parent != null && parent.getNodeType() == Node.DOCUMENT_NODE) {
            return;
        }
        // Add each parent node up to root to the stack
        List<Node> parentElements = new ArrayList<>();
        while (parent != null && parent.getNodeType() != Node.DOCUMENT_NODE) {
            parentElements.add(parent);
            parent = parent.getParentNode();
        }
        // Pop off each node and call startPrefixMapping for each XMLNS attribute
        for (Iterator stackIt = parentElements.iterator(); stackIt.hasNext(); ) {
            NamedNodeMap attrs = parentElements.remove(parentElements.size() - 1).getAttributes();
            if (attrs != null) {
                for (int i=0, length = attrs.getLength(); i < length; i++) {
                    Attr next = (Attr)attrs.item(i);
                    String attrPrefix = next.getPrefix();
                    if (attrPrefix != null && attrPrefix.equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) {
                        contentHandler.startPrefixMapping(next.getLocalName(), next.getValue());
                    }
                }
            }
        }
    }
    protected void reportElementEvents(Element elem) throws SAXException {
        reportElementEvents(elem, null, null);
    }
    protected void reportElementEvents(Element elem, String newUri, String newName) throws SAXException {
        this.currentNode = elem;
        IndexedAttributeList attributes = buildAttributeList(elem);
        String namespaceUri = null;
        String qname = null;
        String lname = null;

        if(newName == null){
            // Handle null local name
            lname = elem.getLocalName();
            if (lname == null) {
                // If local name is null, use the node name
                lname = elem.getNodeName();
                qname = lname;
                handlePrefixedAttribute(elem);
            } else {
                qname = getQName(elem);
            }
            namespaceUri = elem.getNamespaceURI();
            if(namespaceUri == null) {
                namespaceUri = "";
            }
        } else {
            namespaceUri = newUri;
            lname = newName;
            qname = newName;
            if(namespaceUri != null && isNamespaceAware()){
                NamespaceResolver tmpNR = new NamespaceResolver();
                tmpNR.setDOM(elem);

                 String prefix = tmpNR.resolveNamespaceURI(namespaceUri);
                 if(prefix == null || prefix.length() == 0){
                     String defaultNamespace = elem.getAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE);

                     if(defaultNamespace == null){
                         prefix = tmpNR.generatePrefix();
                         contentHandler.startPrefixMapping(prefix, namespaceUri);
                     }else if(defaultNamespace != namespaceUri){
                         prefix = tmpNR.generatePrefix();
                         contentHandler.startPrefixMapping(prefix, namespaceUri);
                     }else{
                         prefix = Constants.EMPTY_STRING;
                     }
                 }

                 if(prefix != null && prefix.length() >0){
                    qname = prefix + Constants.COLON + qname;
                 }
            }

        }



        contentHandler.startElement(namespaceUri, lname, qname, attributes);

        handleChildNodes(elem.getChildNodes());
        contentHandler.endElement(namespaceUri, lname, qname);
        endPrefixMappings(elem);
    }

    protected IndexedAttributeList buildAttributeList(Element elem) throws SAXException {
        IndexedAttributeList attributes = new IndexedAttributeList();
        NamedNodeMap attrs = elem.getAttributes();
        for (int i = 0, length = attrs.getLength(); i < length; i++) {
            Attr next = (Attr)attrs.item(i);
            String attrPrefix = next.getPrefix();
            if(attrPrefix != null && attrPrefix.equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) {
                contentHandler.startPrefixMapping(next.getLocalName(), next.getValue());
                // Handle XMLNS prefixed attributes
                handleNewNamespaceDeclaration(elem, next.getLocalName(), next.getValue());

            } else if(attrPrefix == null) {
                String name = next.getLocalName();
                if(name == null) {
                    name = next.getNodeName();
                }
                if(name != null && name.equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) {
                    contentHandler.startPrefixMapping(Constants.EMPTY_STRING, next.getValue());
                    handleNewNamespaceDeclaration(elem, Constants.EMPTY_STRING, next.getValue());
                }
            }
            if(next.getNamespaceURI() != null && next.getNamespaceURI().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI) && next.getLocalName().equals("type")) {
                handleXsiTypeAttribute(next);
            }
            attributes.addAttribute(next);
        }
        return attributes;
    }

    protected void endPrefixMappings(Element elem) throws SAXException {
        NamedNodeMap attrs = elem.getAttributes();
        for(int i = 0, numOfAtts = attrs.getLength(); i < numOfAtts; i++) {
            Attr next = (Attr)attrs.item(i);
            String attrPrefix = next.getPrefix();
            if (attrPrefix != null && attrPrefix.equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) {
                contentHandler.endPrefixMapping(next.getLocalName());
            } else if(attrPrefix == null) {
                String name = next.getLocalName();
                if(name == null) {
                    name = next.getNodeName();
                }
                if(javax.xml.XMLConstants.XMLNS_ATTRIBUTE.equals(name)) {
                    contentHandler.endPrefixMapping(Constants.EMPTY_STRING);
                }
            }
        }
    }

    protected String getQName(Element elem) throws SAXException {
        handlePrefixedAttribute(elem);
        String prefix = elem.getPrefix();
        if (prefix != null && prefix.length() > 0) {
            String qname = prefix + Constants.COLON + elem.getLocalName();
            return qname;
        } else {
            return elem.getLocalName();
        }
    }

    protected void handleNewNamespaceDeclaration(Element elem, String emptyString, String value) {
        // DO NOTHING
    }

    protected void handleXsiTypeAttribute(Attr attr) throws SAXException {

    }

    /**
     * Handle prefixed attribute - may need to declare the namespace
     * URI locally.
     *
     */
    protected void handlePrefixedAttribute(Element elem) throws SAXException {
        // DO NOTHING
    }

    protected void handleChildNodes(NodeList children) throws SAXException {
        Node nextChild = null;
        if(children.getLength() > 0) {
            nextChild = children.item(0);
        }
        while(nextChild != null) {
            if(nextChild.getNodeType() == Node.TEXT_NODE) {
                char[] value = nextChild.getNodeValue().toCharArray();
                contentHandler.characters(value, 0, value.length);
            } else if(nextChild.getNodeType() == Node.COMMENT_NODE) {
                char[] value = nextChild.getNodeValue().toCharArray();
                if (lexicalHandler != null) {
                    lexicalHandler.comment(value, 0, value.length);
                }
            } else if(nextChild.getNodeType() == Node.ELEMENT_NODE) {
                Element childElement = (Element)nextChild;
                reportElementEvents(childElement);
            } else if(nextChild.getNodeType() == Node.CDATA_SECTION_NODE) {
                if(lexicalHandler != null) {
                    lexicalHandler.startCDATA();
                }
                char[] value = ((CDATASection)nextChild).getData().toCharArray();
                contentHandler.characters(value, 0, value.length);
                if(lexicalHandler != null) {
                    lexicalHandler.endCDATA();
                }
            }
            nextChild = nextChild.getNextSibling();
        }
    }

    /**
     * Trigger an endDocument event on the contenthandler.
     */
    protected void endDocument() throws SAXException {
        contentHandler.endDocument();
    }

    /**
     * Trigger a startDocument event on the contenthandler.
     */
    protected void startDocument() throws SAXException {
        contentHandler.startDocument();
    }

    /**
     * An EclipseLink specific callback into the Reader. This allows Objects to be
     * associated with the XML Nodes they came from.
     */
    @Override
    public void newObjectEvent(Object object, Object parent, Mapping selfRecordMapping) {
        docPresPolicy.addObjectToCache(object, currentNode, selfRecordMapping);
    }

    @Override
    public Object getCurrentObject(CoreAbstractSession session, Mapping selfRecordMapping) {
        //if session == null then this is a marshal of a non-root
        //if docPres policy is null, then we never unmarshalled anything, and can
        //safely return null;
        if(session == null && docPresPolicy == null) {
            return null;
        }
        if(docPresPolicy == null) {
            Login login = (Login)session.getDatasourceLogin();
            docPresPolicy = login.getDocumentPreservationPolicy();
        }
        return docPresPolicy.getObjectForNode(currentNode, selfRecordMapping);
    }

    public DocumentPreservationPolicy getDocPresPolicy() {
        return docPresPolicy;
    }

    public void setDocPresPolicy(DocumentPreservationPolicy policy) {
        docPresPolicy = policy;
    }

    protected void setupLocator(Document doc) {
        LocatorImpl locator = new LocatorImpl();
        try {
            locator.setEncoding(doc.getXmlEncoding());
            locator.setXMLVersion(doc.getXmlVersion());
        } catch(Exception ex) {
            //if unable to invoke these methods, just return and don't invoke
            return;
        }
        this.contentHandler.setDocumentLocator(locator);
    }

    // Made static final for performance reasons.
    /**
     * Implementation of Attributes - used to pass along a given node's attributes
     * to the startElement method of the reader's content handler.
     */
    protected static final class IndexedAttributeList implements org.xml.sax.Attributes {

        private List<Attr> attrs;

        public IndexedAttributeList() {
            attrs = new ArrayList();
        }

        public void addAttribute(Attr attribute) {
            attrs.add(attribute);
        }

        @Override
        public String getQName(int index) {
            try {
                Attr item = attrs.get(index);
                if (item.getName() != null) {
                    return item.getName();
                }
                return Constants.EMPTY_STRING;
            } catch (IndexOutOfBoundsException iobe) {
                return null;
            }
        }

        @Override
        public String getType(String namespaceUri, String localName) {
            return Constants.CDATA;
        }

        @Override
        public String getType(int index) {
            return Constants.CDATA;
        }

        @Override
        public String getType(String qname) {
            return Constants.CDATA;
        }

        @Override
        public int getIndex(String qname) {
            for (int i=0, size = attrs.size(); i<size; i++) {
                if (attrs.get(i).getName().equals(qname)) {
                    return i;
                }
            }
            return -1;
        }

        @Override
        public int getIndex(String uri, String localName) {
            for (int i=0, size = attrs.size(); i<size; i++) {
                Attr item = attrs.get(i);
                try {
                    if (item.getNamespaceURI().equals(uri) && item.getLocalName().equals(localName)) {
                        return i;
                    }
                } catch (Exception x) {}
            }
            return -1;
        }

        @Override
        public int getLength() {
            return attrs.size();
        }

        @Override
        public String getLocalName(int index) {
            try {
                Attr item = attrs.get(index);
                if (item.getLocalName() != null) {
                    return item.getLocalName();
                }
                return item.getName();
            } catch (IndexOutOfBoundsException iobe) {
                return null;
            }
        }

        @Override
        public String getURI(int index) {
            String uri = attrs.get(index).getNamespaceURI();
            if(uri == null) {
                uri = Constants.EMPTY_STRING;
            }
            return uri;
        }

        @Override
        public String getValue(int index) {
            return (attrs.get(index)).getValue();
        }

        @Override
        public String getValue(String qname) {
            for (int i=0, size = attrs.size(); i<size; i++) {
                Attr item = attrs.get(i);
                if (item.getName().equals(qname)) {
                    return item.getValue();
                }
            }
            return null;
        }

        @Override
        public String getValue(String uri, String localName) {
            for (int i=0, size = attrs.size(); i<size; i++) {
                Attr item = attrs.get(i);
                if (item != null) {
                    String itemNS = item.getNamespaceURI();
                    // Need to handle null/empty URI
                    if (item.getNamespaceURI() == null) {
                        itemNS = Constants.EMPTY_STRING;
                    }

                    String itemName = item.getLocalName();
                    if(itemName == null){
                        itemName = item.getNodeName();
                    }
                    if ((itemNS.equals(uri)) && (itemName != null && itemName.equals(localName))) {
                        return item.getValue();
                    }
                }
            }
            return null;
        }
    }

    // Made static final for performance reasons.
    protected static final class LocatorImpl implements Locator2 {

        private String encoding;
        private String version;

        public LocatorImpl() {
            encoding = "UTF-8";
            version = "1.0";
        }

        @Override
        public String getEncoding() {
            return encoding;
        }

        @Override
        public int getColumnNumber() {
            //not supported here
            return 0;
        }

        @Override
        public String getSystemId() {
            return Constants.EMPTY_STRING;
        }

        @Override
        public String getPublicId() {
            return Constants.EMPTY_STRING;
        }

        @Override
        public String getXMLVersion() {
            return version;
        }

        @Override
        public int getLineNumber() {
            //not supported
            return 0;
        }

        protected void setEncoding(String enc) {
            this.encoding = enc;
        }

        protected void setXMLVersion(String xmlVersion) {
            this.version = xmlVersion;
        }

    }

}
