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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext;

/**
 * INTERNAL:
 * <p><b>Purpose</b>:  XPathNodes are used together to build a tree.  The tree
 * is built from all of the XPath statements specified in the mapping metadata
 * (mappings and policies).  This tree is then navigated by an
 * EventObjectBuilder to perform marshal and unmarshal operations.</p>
 * <p>The XPaths "a/b" and "a/c" would result in a tree with the root "a" and
 * two child nodes "b" and "c".</p>
 * <p><b>Responsibilities</b>:<ul>
 * <li>All tree relationships must be bi-directional.</li>
 * <li>Reference a NodeValue, XPathNodes without a Node value represent grouping
 * elements.</li>
 * <li>Reference an XPathFragment, XPathFragments contain name and namespace
 * information.</li>
 * <li>Must differentiate between child nodes that correspond to elements and
 * those that do not.</li>
 * <li>Must represent special mapping situations like any and self mappings.</li>
 * </ul>
 */

public class XPathNode {
    private NodeValue unmarshalNodeValue;
    private NodeValue marshalNodeValue;
    private boolean isMarshalOnlyNodeValue;
    private XPathFragment xPathFragment;
    private XPathNode parent;
    private List<XPathNode> attributeChildren;
    private List<XPathNode> nonAttributeChildren;
    private List<XPathNode> selfChildren;
    private Map<XPathFragment, XPathNode> attributeChildrenMap;
    private Map<String, XPathNode> attributeChildrenLookupTable;
    private boolean isAttributeChildrenLookupTableFilled = false;
    private Map<XPathFragment, XPathNode> nonAttributeChildrenMap;
    private Map<String, XPathNode> nonAttributeChildrenLookupTable;
    private boolean isNonAttributeChildrenLookupTableFilled = false;
    private MappingNodeValue anyAttributeNodeValue;
    private XPathNode anyAttributeNode;
    private XPathNode textNode;
    private XPathNode anyNode;
    private XPathNode nextNode;
    private boolean hasTypeChild;
    private boolean hasPredicateSiblings;
    private boolean hasPredicateChildren;
    private NullCapableValue nullCapableValue;

    public XPathFragment getXPathFragment() {
        return xPathFragment;
    }

    public void setXPathFragment(XPathFragment xPathFragment) {
        this.xPathFragment = xPathFragment;
    }

    public NodeValue getNodeValue() {
        return unmarshalNodeValue;
    }

    public void setNodeValue(NodeValue nodeValue) {
        this.marshalNodeValue = nodeValue;
        this.unmarshalNodeValue = nodeValue;
        if (null != nodeValue) {
            nodeValue.setXPathNode(this);
            isMarshalOnlyNodeValue =  nodeValue.isMarshalOnlyNodeValue();
        }
    }

    public NodeValue getUnmarshalNodeValue() {
        return unmarshalNodeValue;
    }

    public void setUnmarshalNodeValue(NodeValue nodeValue) {
        if (null != nodeValue) {
            nodeValue.setXPathNode(this);
        }
        this.unmarshalNodeValue = nodeValue;
    }

    public NodeValue getMarshalNodeValue() {
        return marshalNodeValue;
    }

    public void setMarshalNodeValue(NodeValue nodeValue) {
        if (null != nodeValue) {
            nodeValue.setXPathNode(this);
        }
        this.marshalNodeValue = nodeValue;
        isMarshalOnlyNodeValue =  marshalNodeValue.isMarshalOnlyNodeValue();
    }

    public NullCapableValue getNullCapableValue() {
        return nullCapableValue;
    }

    public void setNullCapableValue(NullCapableValue nullCapableValue) {
        this.nullCapableValue = nullCapableValue;
    }

    public XPathNode getParent() {
        return parent;
    }

    public void setParent(XPathNode parent) {
        this.parent = parent;
    }

    public List<XPathNode> getAttributeChildren() {
        return this.attributeChildren;
    }

    public List<XPathNode> getNonAttributeChildren() {
        return this.nonAttributeChildren;
    }

    public List<XPathNode> getSelfChildren() {
        return this.selfChildren;
    }

    public Map<XPathFragment, XPathNode> getNonAttributeChildrenMap() {
        return this.nonAttributeChildrenMap;
    }

    public Map<XPathFragment, XPathNode> getAttributeChildrenMap() {
        return this.attributeChildrenMap;
    }

    public boolean isChildrenLookupTableFilled(boolean isAttribute) {
        return isAttribute ? isAttributeChildrenLookupTableFilled : isNonAttributeChildrenLookupTableFilled;
    }

    public void setChildrenLookupTableFilled(boolean isAttribute) {
        if (isAttribute)
            this.isAttributeChildrenLookupTableFilled = true;
        else
            this.isNonAttributeChildrenLookupTableFilled = true;
    }

    public Map<String, XPathNode> getChildrenLookupTable(boolean isAttribute) {
        return isAttribute ? getAttributeChildrenLookupTable() : getNonAttributeChildrenLookupTable();
    }

    private Map<String, XPathNode> getAttributeChildrenLookupTable() {
        if (attributeChildrenLookupTable == null)
            attributeChildrenLookupTable = new HashMap<>();
        return attributeChildrenLookupTable;
    }

    private Map<String, XPathNode> getNonAttributeChildrenLookupTable() {
        if (nonAttributeChildrenLookupTable == null)
            nonAttributeChildrenLookupTable = new HashMap<>();
        return nonAttributeChildrenLookupTable;
    }

    public void setAnyAttributeNodeValue(MappingNodeValue nodeValue) {
        this.anyAttributeNodeValue = nodeValue;
    }

    public MappingNodeValue getAnyAttributeNodeValue() {
        return this.anyAttributeNodeValue;
    }

    public XPathNode getAnyAttributeNode() {
        return this.anyAttributeNode;
    }

    public XPathNode getAnyNode() {
        return this.anyNode;
    }

    public void setAnyNode(XPathNode xPathNode) {
        this.anyNode = xPathNode;
    }

    public XPathNode getNextNode() {
        return nextNode;
    }

    public XPathNode getTextNode() {
        return this.textNode;
    }

    public void setTextNode(XPathNode xPathNode) {
        this.textNode = xPathNode;
    }

    public boolean hasTypeChild() {
        return hasTypeChild;
    }

    @Override
    public boolean equals(Object object) {
        try {
            XPathFragment perfNodeXPathFragment = ((XPathNode)object).getXPathFragment();
            if(xPathFragment == perfNodeXPathFragment) {
                return true;
            } else if(null == xPathFragment) {
                return false;
            } else if(null == perfNodeXPathFragment) {
                return false;
            }
            return xPathFragment.equals(perfNodeXPathFragment);

            // turn fix off for now until we re-enable XMLAnyObjectAndAnyCollectionTestCases
            //          } catch (NullPointerException npe) {
            // b5259059 all cases X0X1 (1mapping xpath=null, 2nd mapping xpath=filled
            // catch when object.getXPathFragment() == null
            // (this will also catch case where perfNode XPath is null)
            //              return false;
        } catch (ClassCastException e) {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return xPathFragment != null ? xPathFragment.hashCode() : 0;
    }

    public XPathNode addChild(XPathFragment anXPathFragment, NodeValue aNodeValue, NamespaceResolver namespaceResolver) {
        if (null != anXPathFragment && anXPathFragment.nameIsText()) {
            if (aNodeValue.isOwningNode(anXPathFragment)) {
                XPathNode textXPathNode = this.getTextNode();
                if(textXPathNode == null) {
                    textXPathNode = new XPathNode();
                }
                textXPathNode.setParent(this);
                textXPathNode.setXPathFragment(anXPathFragment);
                if (aNodeValue.isMarshalNodeValue()) {
                    textXPathNode.setMarshalNodeValue(aNodeValue);
                }
                if (aNodeValue.isUnmarshalNodeValue()) {
                    textXPathNode.setUnmarshalNodeValue(aNodeValue);
                }
                this.setTextNode(textXPathNode);
                if(null != nonAttributeChildren && !nonAttributeChildren.contains(textXPathNode)) {
                    nonAttributeChildren.add(textXPathNode);
                }
                if(aNodeValue instanceof XMLCompositeObjectMappingNodeValue) {
                    if (null == selfChildren) {
                        selfChildren = new ArrayList<>();
                    }
                    selfChildren.add(textXPathNode);
                }
                return textXPathNode;
            }
        }

        if (anXPathFragment != null && namespaceResolver != null && anXPathFragment.getNamespaceURI() == null && !anXPathFragment.nameIsText()) {
            if(!anXPathFragment.isAttribute()) {
                anXPathFragment.setNamespaceURI(namespaceResolver.resolveNamespacePrefix(anXPathFragment.getPrefix()));
            } else if(anXPathFragment.hasNamespace()) {
                anXPathFragment.setNamespaceURI(namespaceResolver.resolveNamespacePrefix(anXPathFragment.getPrefix()));
            }
        }

        XPathNode xPathNode = new XPathNode();
        xPathNode.setXPathFragment(anXPathFragment);

        List<XPathNode> children;
        Map childrenMap;

        if ((anXPathFragment != null) && anXPathFragment.isAttribute()) {
            if (null == attributeChildren) {
                attributeChildren = new ArrayList();
            }
            if (null == attributeChildrenMap) {
                attributeChildrenMap = new HashMap();
            }
            children = attributeChildren;
            childrenMap = attributeChildrenMap;
        } else {
            if (null == nonAttributeChildren) {
                nonAttributeChildren = new ArrayList();
                if(null != textNode) {
                    nonAttributeChildren.add(textNode);
                }
            }
            if (null == nonAttributeChildrenMap) {
                //The reason behind LinkedHashMap is the order of items when for-cycling HashMap.getEntrySet() or HashMap.getKeySet().
                //This change fixes non-determinism (implementation in JDK8 has changed so the order is different (sometimes) than in JDK6 and JDK7).
                nonAttributeChildrenMap = new LinkedHashMap();
            }
            if(anXPathFragment !=null && Constants.SCHEMA_TYPE_ATTRIBUTE.equals(anXPathFragment.getLocalName())){
        hasTypeChild = true;
            }
            children = nonAttributeChildren;
            childrenMap = nonAttributeChildrenMap;
        }

        if (null == anXPathFragment) {
            if(aNodeValue.isMarshalNodeValue()) {
                xPathNode.setMarshalNodeValue(aNodeValue);
            }
            if(aNodeValue.isUnmarshalNodeValue() && xPathNode.getUnmarshalNodeValue() == null) {
                xPathNode.setUnmarshalNodeValue(aNodeValue);
            }
            xPathNode.setParent(this);
            if (aNodeValue instanceof XMLAnyAttributeMappingNodeValue || (aNodeValue instanceof XMLVariableXPathObjectMappingNodeValue && ((XMLVariableXPathObjectMappingNodeValue)aNodeValue).getMapping().isAttribute() ) || (aNodeValue instanceof XMLVariableXPathCollectionMappingNodeValue && ((XMLVariableXPathCollectionMappingNodeValue)aNodeValue).getMapping().isAttribute() )) {
                setAnyAttributeNodeValue((MappingNodeValue)aNodeValue);
                anyAttributeNode = xPathNode;
            } else {
                if(!children.contains(xPathNode)) {
                    children.add(xPathNode);
                }
                setAnyNode(xPathNode);
            }
            return xPathNode;
        }
        this.hasPredicateChildren = hasPredicateChildren || anXPathFragment.getPredicate() != null;
        if(this.getNonAttributeChildren() != null && this.hasPredicateChildren) {
            for(XPathNode nextChild: this.getNonAttributeChildren()) {
                XPathFragment nextFrag = nextChild.getXPathFragment();
                if(nextFrag != null && nextFrag.equals(anXPathFragment, true)) {
                    if(nextFrag.getPredicate() == null && anXPathFragment.getPredicate() != null) {
                        nextChild.setHasPredicateSiblings(true);
                    } else if(anXPathFragment.getPredicate() == null && nextFrag.getPredicate() != null) {
                        xPathNode.setHasPredicateSiblings(true);
                    }
                }
            }
        }

        boolean isSelfFragment = XPathFragment.SELF_FRAGMENT.equals(anXPathFragment);
        if(isSelfFragment){
            children.add(xPathNode);
            if (null == selfChildren) {
                selfChildren = new ArrayList<>();
            }
            selfChildren.add(xPathNode);
        }else{
            int index = children.indexOf(xPathNode);
            if (index >= 0) {
                xPathNode = children.get(index);
            } else {
                xPathNode.setParent(this);
                if(!children.contains(xPathNode)) {
                    int childrenSize = children.size();
                    if (childrenSize > 0) {
                        children.get(childrenSize - 1).nextNode = xPathNode;
                    }
                    children.add(xPathNode);
                }
                childrenMap.put(anXPathFragment, xPathNode);
            }
        }

        if (aNodeValue.isOwningNode(anXPathFragment)) {
            if(aNodeValue.isMarshalNodeValue()) {
                xPathNode.setMarshalNodeValue(aNodeValue);
            }
            if(aNodeValue.isUnmarshalNodeValue() && xPathNode.getUnmarshalNodeValue() == null) {
                xPathNode.setUnmarshalNodeValue(aNodeValue);
            }
        } else {
            XPathFragment nextFragment = anXPathFragment.getNextFragment();
            xPathNode.addChild(nextFragment, aNodeValue, namespaceResolver);
        }
        return xPathNode;
    }

    private void setHasPredicateSiblings(boolean b) {
        this.hasPredicateSiblings = b;
    }

    public boolean hasPredicateSiblings() {
        return this.hasPredicateSiblings;
    }

    public boolean marshal(MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver, Marshaller marshaller, MarshalContext marshalContext, XPathFragment rootFragment) {
        if ((null == marshalNodeValue) || isMarshalOnlyNodeValue) {
            if(marshalRecord.isWrapperAsCollectionName() && null != nonAttributeChildren && nonAttributeChildren.size() == 1) {
                XPathNode childXPathNode = nonAttributeChildren.get(0);
                NodeValue childXPathNodeUnmarshalNodeValue = childXPathNode.getUnmarshalNodeValue();
                if(childXPathNodeUnmarshalNodeValue != null && childXPathNodeUnmarshalNodeValue.isContainerValue()) {
                    ContainerValue containerValue = (ContainerValue) childXPathNodeUnmarshalNodeValue;
                    if(containerValue.isWrapperAllowedAsCollectionName()) {
                        XPathNode wrapperXPathNode = new XPathNode();
                        wrapperXPathNode.setXPathFragment(this.getXPathFragment());
                        wrapperXPathNode.setMarshalNodeValue(childXPathNode.getMarshalNodeValue());
                        return wrapperXPathNode.marshal(marshalRecord, object, session, namespaceResolver, marshaller, marshalContext, rootFragment);
                    }
                }
            }
            marshalRecord.addGroupingElement(this);

            boolean hasValue = false;
            if (null != attributeChildren) {
                for (int x = 0, size = attributeChildren.size(); x < size; x++) {
                    XPathNode xPathNode = attributeChildren.get(x);
                    hasValue = xPathNode.marshal(marshalRecord, object, session, namespaceResolver, marshaller, ObjectMarshalContext.getInstance(), this.xPathFragment) || hasValue;
                }
            }
            if (anyAttributeNode != null) {
                hasValue = anyAttributeNode.marshal(marshalRecord, object, session, namespaceResolver, marshaller, ObjectMarshalContext.getInstance(), null) || hasValue;
            }
            if (null == nonAttributeChildren) {
                if (textNode != null) {
                    hasValue = textNode.marshal(marshalRecord, object, session, namespaceResolver, marshaller, ObjectMarshalContext.getInstance(), null) || hasValue;
                }
            } else {
                for (int x = 0, size = marshalContext.getNonAttributeChildrenSize(this); x < size; x++) {
                    XPathNode xPathNode = (XPathNode)marshalContext.getNonAttributeChild(x, this);
                    MarshalContext childMarshalContext = marshalContext.getMarshalContext(x);
                    hasValue = xPathNode.marshal(marshalRecord, object, session, namespaceResolver, marshaller, childMarshalContext, this.xPathFragment) || hasValue;
                }
            }

            if (hasValue) {
                marshalRecord.endElement(xPathFragment, namespaceResolver);
            } else {
                marshalRecord.removeGroupingElement(this);
            }

            return hasValue;
        } else {
            if(marshalNodeValue.isMappingNodeValue()) {
                Mapping mapping = ((MappingNodeValue)marshalNodeValue).getMapping();
                CoreAttributeGroup currentGroup = marshalRecord.getCurrentAttributeGroup();
                if(!(currentGroup.containsAttributeInternal(mapping.getAttributeName()))) {
                    return false;
                }
            }
            return marshalContext.marshal(marshalNodeValue, xPathFragment, marshalRecord, object, session, namespaceResolver, rootFragment);
        }
    }

    public boolean startElement(MarshalRecord marshalRecord, XPathFragment anXPathFragment, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver, ObjectBuilder compositeObjectBuilder, Object compositeObject) {
        if (null == anXPathFragment) {
            return false;
        }

        marshalRecord.openStartElement(anXPathFragment, namespaceResolver);
        boolean hasValue = false;

        marshalRecord.predicateAttribute(anXPathFragment, namespaceResolver);

        if (null != attributeChildren) {
            for (int x = 0, size = attributeChildren.size(); x < size; x++) {
                XPathNode attributeNode = attributeChildren.get(x);
                hasValue = attributeNode.marshal(marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance(), null) || hasValue;
            }
        }
        if (anyAttributeNode != null) {
            //marshal the anyAttribute node here before closeStartElement()
            hasValue = anyAttributeNode.marshal(marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance(), null) || hasValue;
        }

        if (null != compositeObjectBuilder) {
            hasValue = compositeObjectBuilder.marshalAttributes(marshalRecord, compositeObject, session) || hasValue;
        }
        marshalRecord.closeStartElement();
        return hasValue;
    }

    /**
     * Marshal any 'self' mapped attributes.
     *
     */
    public boolean marshalSelfAttributes(MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver, Marshaller marshaller) {
        if (marshalNodeValue == null) {
            return false;
        }
        return marshalNodeValue.marshalSelfAttributes(xPathFragment, marshalRecord, object, session, namespaceResolver, marshaller);
    }

    public boolean isWhitespaceAware() {
        return unmarshalNodeValue.isWhitespaceAware();
    }

}
