/*
 * Copyright (c) 1998, 2020 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.Collection;
import java.util.Map;

import org.eclipse.persistence.core.sessions.CoreSession;
import org.eclipse.persistence.internal.core.queries.CoreContainerPolicy;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.AnyCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.ChoiceCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.CollectionReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.CompositeCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.DirectCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.Field;
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.UnmarshalContext;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;

import org.xml.sax.Attributes;

/**
 * INTERNAL:
 * <p><b>Purpose</b>: This is how the XML Choice Collection Mapping is
 * handled when used with the TreeObjectBuilder.</p>
 * @author mmacivor
 */
public class XMLChoiceCollectionMappingUnmarshalNodeValue extends MappingNodeValue implements ContainerValue {
    private NodeValue choiceElementNodeValue;
    private NodeValue choiceElementMarshalNodeValue;
    private ChoiceCollectionMapping xmlChoiceCollectionMapping;
    private Mapping nestedMapping;
    private Map<Field, NodeValue> fieldToNodeValues;
    private Field xmlField;
    private ContainerValue containerNodeValue;
    private boolean isMixedNodeValue;
    private boolean isAny;
    private int index = -1;

    public XMLChoiceCollectionMappingUnmarshalNodeValue(ChoiceCollectionMapping mapping, Field xmlField) {
        this.xmlChoiceCollectionMapping = mapping;
        this.xmlField = xmlField;
        if(xmlField == null && mapping.isAny()){
            isAny = true;
        }else{
          this.nestedMapping = (Mapping)mapping.getChoiceElementMappings().get(xmlField);
        }
        initializeNodeValue();
    }

    public XMLChoiceCollectionMappingUnmarshalNodeValue(ChoiceCollectionMapping mapping, Field xmlField, Mapping nestedMapping) {
        this.xmlChoiceCollectionMapping = mapping;
        this.xmlField = xmlField;
        this.nestedMapping = nestedMapping;
        initializeNodeValue();
    }

    @Override
    public boolean isOwningNode(XPathFragment xPathFragment) {
        if(isMixedNodeValue) {
            if(xPathFragment.nameIsText()) {
                return true;
            } else {
                return false;
            }
        }
        return choiceElementNodeValue.isOwningNode(xPathFragment);
    }

    private void initializeNodeValue() {
        if(nestedMapping == null && isAny){
            nestedMapping = xmlChoiceCollectionMapping.getAnyMapping();
        }
        Mapping xmlMapping = this.nestedMapping;
        if(xmlMapping instanceof BinaryDataCollectionMapping) {
            choiceElementNodeValue = new XMLBinaryDataCollectionMappingNodeValue((BinaryDataCollectionMapping)xmlMapping);
            choiceElementMarshalNodeValue = choiceElementNodeValue;
        } else if(xmlMapping instanceof DirectCollectionMapping) {
            choiceElementNodeValue = new XMLCompositeDirectCollectionMappingNodeValue((DirectCollectionMapping)xmlMapping);
            choiceElementMarshalNodeValue = choiceElementNodeValue;
        } else if(xmlMapping instanceof CompositeCollectionMapping){
            choiceElementNodeValue = new XMLCompositeCollectionMappingNodeValue((CompositeCollectionMapping)xmlMapping);
            choiceElementMarshalNodeValue = choiceElementNodeValue;
        }else if(xmlMapping instanceof AnyCollectionMapping){
            choiceElementNodeValue = new XMLAnyCollectionMappingNodeValue((AnyCollectionMapping)xmlMapping);
            choiceElementMarshalNodeValue = choiceElementNodeValue;
        } else {
            choiceElementNodeValue = new XMLCollectionReferenceMappingNodeValue((CollectionReferenceMapping)xmlMapping, xmlField);
             CollectionReferenceMapping refMapping = ((CollectionReferenceMapping)xmlMapping);
             if(refMapping.usesSingleNode() || refMapping.getFields().size() == 1) {
                 choiceElementMarshalNodeValue = new XMLCollectionReferenceMappingNodeValue(refMapping, xmlField);

             } else {
                 choiceElementMarshalNodeValue = new XMLCollectionReferenceMappingMarshalNodeValue((CollectionReferenceMapping)xmlMapping);
             }
        }
    }

    public void setContainerNodeValue(XMLChoiceCollectionMappingUnmarshalNodeValue nodeValue) {
        this.containerNodeValue = nodeValue;
    }

    public void setNullValue(Object object, CoreSession session) {
        xmlChoiceCollectionMapping.setAttributeValueInObject(object, null);
    }

    @Override
    public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
        Object collection = unmarshalRecord.getContainerInstance(this.containerNodeValue);

        if(null != xmlChoiceCollectionMapping.getConverter()) {
            UnmarshalContext unmarshalContext = unmarshalRecord.getUnmarshalContext();
            unmarshalRecord.setUnmarshalContext(new ChoiceUnmarshalContext(unmarshalContext, xmlChoiceCollectionMapping));
            this.choiceElementNodeValue.endElement(xPathFragment, unmarshalRecord, collection);
            unmarshalRecord.setUnmarshalContext(unmarshalContext);
        } else {
            this.choiceElementNodeValue.endElement(xPathFragment, unmarshalRecord, collection);
        }
    }

    @Override
    public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) {
        return this.choiceElementNodeValue.startElement(xPathFragment, unmarshalRecord, atts);
    }

    @Override
    public void setXPathNode(XPathNode xPathNode) {
        super.setXPathNode(xPathNode);
        this.choiceElementNodeValue.setXPathNode(xPathNode);
    }

    @Override
    public Object getContainerInstance() {
        return getContainerPolicy().containerInstance();
    }

    @Override
    public void setContainerInstance(Object object, Object containerInstance) {
        xmlChoiceCollectionMapping.setAttributeValueInObject(object, containerInstance);
    }

    @Override
    public CoreContainerPolicy getContainerPolicy() {
        return xmlChoiceCollectionMapping.getContainerPolicy();
    }

    @Override
    public boolean isContainerValue() {
        return true;
    }

    @Override
    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object value, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
        //empty impl in the unmarshal node value
        return false;
    }

    @Override
    public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) {
        //dummy impl in the unmarshal node value
        return false;
    }

    public NodeValue getChoiceElementNodeValue() {
        return this.choiceElementNodeValue;
    }

    public NodeValue getChoiceElementMarshalNodeValue() {
        return this.choiceElementMarshalNodeValue;
    }

    @Override
    public boolean isUnmarshalNodeValue() {
        return true;
    }

    @Override
    public boolean isWrapperAllowedAsCollectionName() {
        return false;
    }

    @Override
    public boolean isMarshalNodeValue() {
        return false;
    }

    @Override
    public ChoiceCollectionMapping getMapping() {
        return xmlChoiceCollectionMapping;
    }

    @Override
    public boolean getReuseContainer() {
        return getMapping().getReuseContainer();
    }

    public void setFieldToNodeValues(Map<Field, NodeValue> fieldToNodeValues) {
        this.fieldToNodeValues = fieldToNodeValues;
    }

    public Collection<NodeValue> getAllNodeValues() {
        return this.fieldToNodeValues.values();
    }

    /**
     * The underlying choice element node value will handle attributes.
     *
     */
    @Override
    public void attribute(UnmarshalRecord unmarshalRecord, String URI, String localName, String value) {
        this.choiceElementNodeValue.attribute(unmarshalRecord, URI, localName, value);
    }

    /**
     * INTERNAL:
     * Indicates that this is the choice mapping node value that represents the mixed content.
     */
    public void setIsMixedNodeValue(boolean isMixed) {
        this.isMixedNodeValue = isMixed;
    }

    /**
     * INTERNAL:
     * Return true if this is the node value representing mixed content.
     */
    @Override
    public boolean isMixedContentNodeValue() {
        return this.isMixedNodeValue;
    }

    /**
     *  INTERNAL:
     *  Used to track the index of the corresponding containerInstance in the containerInstances Object[] on UnmarshalRecord
     */
    @Override
    public void setIndex(int index){
        this.index = index;
    }

    /**
     * INTERNAL:
     * Set to track the index of the corresponding containerInstance in the containerInstances Object[] on UnmarshalRecord
     * Set during TreeObjectBuilder initialization
     */
    @Override
    public int getIndex(){
        return index;
    }

    /**
     * INTERNAL
     * Return true if an empty container should be set on the object if there
     * is no presence of the collection in the XML document.
     * @since EclipseLink 2.3.3
     */
    @Override
    public boolean isDefaultEmptyContainer() {
        return getMapping().isDefaultEmptyContainer();
    }

}
