/*
 * 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:
//     bdoughan - October 21/2009 - 2.0 - Initial implementation
package org.eclipse.persistence.internal.oxm;

import java.util.List;
import javax.xml.namespace.QName;

import org.eclipse.persistence.internal.core.queries.CoreContainerPolicy;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.CollectionReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext;

public class XMLCollectionReferenceMappingMarshalNodeValue extends MappingNodeValue implements ContainerValue {

    private CollectionReferenceMapping xmlCollectionReferenceMapping;
    private XPathNode branchNode;
    private int index = -1;

    public XMLCollectionReferenceMappingMarshalNodeValue(CollectionReferenceMapping xmlCollectionReferenceMapping) {
        this.xmlCollectionReferenceMapping = xmlCollectionReferenceMapping;
        branchNode = new XPathNode();
        NamespaceResolver namespaceResolver = ((Descriptor) xmlCollectionReferenceMapping.getDescriptor()).getNamespaceResolver();
        List fkFields = xmlCollectionReferenceMapping.getFields();
        for(int x=0, fkFieldsSize=fkFields.size(); x<fkFieldsSize; x++) {
            Field fkField = (Field) fkFields.get(x);
            branchNode.addChild(fkField.getXPathFragment(), new XMLCollectionReferenceMappingFKMarshalNodeValue(xmlCollectionReferenceMapping, fkField), namespaceResolver);
        }
    }

    @Override
    public boolean isOwningNode(XPathFragment fragment) {
        return true;
    }

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

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

    @Override
    public CollectionReferenceMapping getMapping() {
        return xmlCollectionReferenceMapping;
    }

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

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

    @Override
    public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) {
        if (xmlCollectionReferenceMapping.isReadOnly()) {
            return false;
        }

        Object collection = xmlCollectionReferenceMapping.getAttributeAccessor().getAttributeValueFromObject(object);
        if (null == collection) {
            return false;
        }
        CoreContainerPolicy cp = getContainerPolicy();
        Object iterator = cp.iteratorFor(collection);
        if (cp.hasNext(iterator)) {
            XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
            marshalRecord.closeStartGroupingElements(groupingFragment);
        } else {
            return marshalRecord.emptyCollection(xPathFragment, namespaceResolver, false);
        }
        marshalRecord.startCollection();

        if(xPathFragment != XPathFragment.SELF_FRAGMENT) {
            marshalRecord.openStartElement(xPathFragment, namespaceResolver);
        }
        while (cp.hasNext(iterator)) {
            Object objectValue = cp.next(iterator, session);
            marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, ObjectMarshalContext.getInstance());
        }
        if(xPathFragment != XPathFragment.SELF_FRAGMENT) {
            marshalRecord.endElement(xPathFragment, namespaceResolver);
        }
        marshalRecord.endCollection();

        return true;
    }

    @Override
    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object value, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
        if (xmlCollectionReferenceMapping.usesSingleNode()) {
            XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
            if (xPathFragment.isAttribute()) {
                marshalRecord.attribute(xPathFragment, namespaceResolver, (String) value);
                marshalRecord.closeStartGroupingElements(groupingFragment);
            } else {
                marshalRecord.closeStartGroupingElements(groupingFragment);
                marshalRecord.characters((String) value);
            }
        } else {
            for (int x = 0, size = marshalContext.getNonAttributeChildrenSize(branchNode); x < size; x++) {
                XPathNode xPathNode = (XPathNode)marshalContext.getNonAttributeChild(x, branchNode);
                xPathNode.marshal(marshalRecord, value, session, namespaceResolver, marshalRecord.getMarshaller(), marshalContext.getMarshalContext(x), null);
            }

        }
        return true;
    }

    @Override
    public boolean isMarshalNodeValue() {
        return !xmlCollectionReferenceMapping.usesSingleNode();
    }

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

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

    private static class XMLCollectionReferenceMappingFKMarshalNodeValue extends MappingNodeValue {

        private CollectionReferenceMapping xmlCollectionReferenceMapping;
        private Field xmlField;

        public XMLCollectionReferenceMappingFKMarshalNodeValue(CollectionReferenceMapping xmlCollectionReferenceMapping, Field xmlField) {
            this.xmlCollectionReferenceMapping = xmlCollectionReferenceMapping;
            this.xmlField = xmlField;
        }

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

        @Override
        public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) {
            XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
            marshalRecord.closeStartGroupingElements(groupingFragment);
            return marshalSingleValue(xPathFragment, marshalRecord, null, object, session, namespaceResolver, ObjectMarshalContext.getInstance());
        }

        @Override
        public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object value, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
            Object fieldValue = xmlCollectionReferenceMapping.buildFieldValue(value, xmlField, session);
            if (fieldValue == null) {
                if(null != value) {
                    Field f2 = (Field) xmlCollectionReferenceMapping.getSourceToTargetKeyFieldAssociations().get(xmlField);
                    fieldValue = marshalRecord.getMarshaller().getContext().getValueByXPath(value, f2.getXPath(), f2.getNamespaceResolver(), Object.class);
                }
                if(null == fieldValue) {
                    return false;
                }
            }
            QName schemaType = xmlField.getSchemaTypeForValue(fieldValue, session);
            if (xPathFragment.isAttribute()) {
                marshalRecord.attribute(xPathFragment, namespaceResolver, fieldValue, schemaType);
                marshalRecord.closeStartElement();
            } else {
                marshalRecord.closeStartElement();
                marshalRecord.characters(schemaType, fieldValue, null, false);
            }
            return true;

        }

        @Override
        public CollectionReferenceMapping getMapping() {
            return xmlCollectionReferenceMapping;
        }

    }

    /**
     *  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();
    }

}
