/*
 * 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.StringTokenizer;
import javax.xml.namespace.QName;

import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.core.queries.CoreContainerPolicy;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.DirectCollectionMapping;
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;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;

import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType;
import org.xml.sax.Attributes;

/**
 * INTERNAL:
 * <p><b>Purpose</b>: This is how the XML Composite Direct Collection Mapping is
 * handled when used with the TreeObjectBuilder.</p>
 */

public class XMLCompositeDirectCollectionMappingNodeValue extends MappingNodeValue implements ContainerValue {
    private static final String SPACE = " ";
    private DirectCollectionMapping xmlCompositeDirectCollectionMapping;
    private int index = -1;

    public XMLCompositeDirectCollectionMappingNodeValue(DirectCollectionMapping xmlCompositeDirectCollectionMapping) {
        super();
        this.xmlCompositeDirectCollectionMapping = xmlCompositeDirectCollectionMapping;
    }

    @Override
    public boolean isOwningNode(XPathFragment xPathFragment) {
         XPathFragment nextFragment = xPathFragment.getNextFragment();
         if (nextFragment == null || xmlCompositeDirectCollectionMapping.usesSingleNode()) {
             return xPathFragment.isAttribute() || xPathFragment.nameIsText();
         } else {
             return  (nextFragment != null) && (nextFragment.nameIsText() || nextFragment.isAttribute());
         }
    }

    /**
     * Override the method in XPathNode such that the marshaller can be set on the
     * marshalRecord - this is required for XMLConverter usage.
     */
    @Override
    public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) {
        if (xmlCompositeDirectCollectionMapping.isReadOnly()) {
            return false;
        }

        CoreContainerPolicy cp = getContainerPolicy();
        Object collection = xmlCompositeDirectCollectionMapping.getAttributeAccessor().getAttributeValueFromObject(object);
        if (null == collection) {
            AbstractNullPolicy wrapperNP = xmlCompositeDirectCollectionMapping.getWrapperNullPolicy();
            if (wrapperNP != null && wrapperNP.getMarshalNullRepresentation() == XMLNullRepresentationType.XSI_NIL) {
                marshalRecord.nilSimple(namespaceResolver);
                return true;
            } else {
                return false;
            }
        }

        Object iterator = cp.iteratorFor(collection);
        Field xmlField = (Field) xmlCompositeDirectCollectionMapping.getField();
        if (null != iterator && cp.hasNext(iterator)) {
            XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
            marshalRecord.closeStartGroupingElements(groupingFragment);
        } else {
            if (xmlField.usesSingleNode() && !xmlCompositeDirectCollectionMapping.isDefaultEmptyContainer()) {
                XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
                marshalRecord.closeStartGroupingElements(groupingFragment);
            } else {
                return marshalRecord.emptyCollection(xPathFragment, namespaceResolver, xmlCompositeDirectCollectionMapping.getWrapperNullPolicy() != null);
            }
        }

        Object objectValue;
        if (xmlField.usesSingleNode()) {
            StringBuilder stringValueStringBuilder = new StringBuilder();
            String newValue;
            QName schemaType = null;
            if (xPathFragment != null && !xPathFragment.isAttribute() && !xPathFragment.nameIsText) {
                marshalRecord.openStartElement(xPathFragment, namespaceResolver);
            }

            while (cp.hasNext(iterator)) {
                objectValue = cp.next(iterator, session);
                objectValue = xmlCompositeDirectCollectionMapping.convertObjectValueToDataValue(objectValue, session, marshalRecord.getMarshaller());
                schemaType = xmlField.getSchemaTypeForValue(objectValue, session);

                newValue = marshalRecord.getValueToWrite(schemaType, objectValue, (ConversionManager) session.getDatasourcePlatform().getConversionManager());
                if (null != newValue) {
                    stringValueStringBuilder.append(newValue);
                    if (cp.hasNext(iterator)) {
                        stringValueStringBuilder.append(SPACE);
                    }
                }
            }

            XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
            if (xPathFragment != null && xPathFragment.isAttribute()) {
                marshalRecord.attribute(xPathFragment, namespaceResolver, stringValueStringBuilder.toString());
                marshalRecord.closeStartGroupingElements(groupingFragment);
            } else {
                marshalRecord.closeStartGroupingElements(groupingFragment);
                if (xmlCompositeDirectCollectionMapping.isCDATA()) {
                    marshalRecord.cdata(stringValueStringBuilder.toString());
                } else {
                    marshalRecord.characters(stringValueStringBuilder.toString());
                    if (xPathFragment != null && !xPathFragment.isAttribute() && !xPathFragment.nameIsText) {
                        marshalRecord.endElement(xPathFragment, namespaceResolver);
                    }
                }
            }
        } else {
            int valueSize = cp.sizeFor(collection);
            if(marshalRecord.getMarshaller().isApplicationJSON() && (valueSize > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
                marshalRecord.startCollection();
            }

            while (cp.hasNext(iterator)) {
                objectValue = cp.next(iterator, session);
                marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, ObjectMarshalContext.getInstance());
            }
            if(marshalRecord.getMarshaller().isApplicationJSON() && (valueSize > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
                marshalRecord.endCollection();
            }
        }
        return true;
    }

    @Override
    public void attribute(UnmarshalRecord unmarshalRecord, String namespaceURI, String localName, String value) {
        Object collection = unmarshalRecord.getContainerInstance(this);
        if (xmlCompositeDirectCollectionMapping.usesSingleNode()) {
            StringTokenizer stringTokenizer = new StringTokenizer(value);
            while (stringTokenizer.hasMoreTokens()) {
                addUnmarshalValue(unmarshalRecord, stringTokenizer.nextToken(), collection);
            }
        } else {
            addUnmarshalValue(unmarshalRecord, value, collection);
        }
    }

    @Override
    public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) {
        Field xmlField = (Field) xmlCompositeDirectCollectionMapping.getField();
        XPathFragment lastXPathFragment = xmlField.getLastXPathFragment();
        if (lastXPathFragment.nameIsText()) {
            String type = atts.getValue(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_TYPE_ATTRIBUTE);
            if (null != type) {
                String namespaceURI = null;
                int colonIndex = type.indexOf(Constants.COLON);
                if (colonIndex > -1) {
                    String prefix = type.substring(0, colonIndex);
                    namespaceURI = unmarshalRecord.resolveNamespacePrefix(prefix);
                    type = type.substring(colonIndex + 1);
                }
                unmarshalRecord.setTypeQName(new QName(namespaceURI, type));
            }
        } else if (lastXPathFragment.isAttribute()) {
            if (!xmlField.usesSingleNode()) {
                String namespaceURI = lastXPathFragment.getNamespaceURI();
                if (namespaceURI == null) {
                    namespaceURI = Constants.EMPTY_STRING;
                }
                String value = atts.getValue(namespaceURI, lastXPathFragment.getLocalName());
                Object collection = unmarshalRecord.getContainerInstance(this);
                addUnmarshalValue(unmarshalRecord, value, collection);
            }
        }
        return true;
    }

    @Override
    public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
        Field xmlField = (Field) xmlCompositeDirectCollectionMapping.getField();

        Object value = unmarshalRecord.getCharacters().toString();
        if(((String)value).length() == 0 && !xmlField.usesSingleNode()){
            if( xmlCompositeDirectCollectionMapping.getNullValue() != null){
                value = xmlCompositeDirectCollectionMapping.getNullValue();
            }
        }
        unmarshalRecord.resetStringBuffer();
        XPathFragment lastXPathFragment = xmlField.getLastXPathFragment();
        if (!lastXPathFragment.nameIsText()) {
            return;
        }

        if (xmlField.usesSingleNode() ) {

            Object collection = unmarshalRecord.getContainerInstance(this);
            StringTokenizer stringTokenizer = new StringTokenizer((String)value);
            while (stringTokenizer.hasMoreTokens()) {
                addUnmarshalValue(unmarshalRecord, stringTokenizer.nextToken(), collection);
            }
        } else {
            if(!unmarshalRecord.getXMLReader().isInCollection() && unmarshalRecord.isNil() ){
                unmarshalRecord.setAttributeValueNull(this);
            }else{
                Object collection = unmarshalRecord.getContainerInstance(this);
                addUnmarshalValue(unmarshalRecord, value, collection);
            }
        }
    }

    @Override
    public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Object collection) {
        Field xmlField = (Field) xmlCompositeDirectCollectionMapping.getField();

        Object value = unmarshalRecord.getCharacters().toString();
        if(((String)value).length() == 0 && !xmlField.usesSingleNode()){
            if( xmlCompositeDirectCollectionMapping.getNullValue() != null){
                value = xmlCompositeDirectCollectionMapping.getNullValue();
            }
        }
        unmarshalRecord.resetStringBuffer();

        if (xmlField.usesSingleNode() && value instanceof String) {
            StringTokenizer stringTokenizer = new StringTokenizer((String)value);
            while (stringTokenizer.hasMoreTokens()) {
                addUnmarshalValue(unmarshalRecord, stringTokenizer.nextToken(), collection);
            }
        } else {
            if (xmlField.getLastXPathFragment().nameIsText()) {
                if(!unmarshalRecord.getXMLReader().isInCollection() && unmarshalRecord.isNil() ){
                    unmarshalRecord.setAttributeValueNull(this);
                } else{
                    addUnmarshalValue(unmarshalRecord, value, collection);
                }
            }
        }
    }

    private void addUnmarshalValue(UnmarshalRecord unmarshalRecord, Object value, Object collection) {

        if (unmarshalRecord.isNil() && unmarshalRecord.getXMLReader().isNullRepresentedByXsiNil(xmlCompositeDirectCollectionMapping.getNullPolicy())){
            value = null;
        } else if (!isWhitespaceAware() && Constants.EMPTY_STRING.equals(value)) {
            value = null;
        }

        Field xmlField = (Field) xmlCompositeDirectCollectionMapping.getField();

        ConversionManager conversionManager = unmarshalRecord.getConversionManager();
        if (unmarshalRecord.getTypeQName() != null) {
            Class<?> typeClass = xmlField.getJavaClass(unmarshalRecord.getTypeQName(), conversionManager);
            value = conversionManager.convertObject(value, typeClass, unmarshalRecord.getTypeQName());
        } else {
            value = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, conversionManager, unmarshalRecord);
        }

        value = xmlCompositeDirectCollectionMapping.convertDataValueToObjectValue(value, unmarshalRecord.getSession(), unmarshalRecord.getUnmarshaller());

        if (value != null && value.getClass() == CoreClassConstants.STRING) {
            if (xmlCompositeDirectCollectionMapping.isCollapsingStringValues()) {
                value = conversionManager.collapseStringValue((String)value);
            } else if (xmlCompositeDirectCollectionMapping.isNormalizingStringValues()) {
                value = conversionManager.normalizeStringValue((String)value);
            }
        }
        unmarshalRecord.addAttributeValue(this, value, collection);
    }

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

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

    @Override
    public CoreContainerPolicy getContainerPolicy() {
        return xmlCompositeDirectCollectionMapping.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) {
        value = xmlCompositeDirectCollectionMapping.convertObjectValueToDataValue(value, session, marshalRecord.getMarshaller());

        if (null != value) {
            Field xmlField = (Field) xmlCompositeDirectCollectionMapping.getField();
            QName schemaType = xmlField.getSchemaTypeForValue(value, session);
            boolean isElementOpen = false;
            if (Constants.QNAME_QNAME.equals(schemaType)) {
                QName fieldValue = (QName) value;
                if ((fieldValue.getNamespaceURI() == null || fieldValue.getNamespaceURI().equals("")) && marshalRecord.getNamespaceResolver().getDefaultNamespaceURI() != null) {
                    // In this case, an extra xmlns="" declaration is going to be added. This may
                    // require adjusting the namespace of the current fragment.
                    String defaultNamespaceURI = namespaceResolver.getDefaultNamespaceURI();
                    if (defaultNamespaceURI.equals(xPathFragment.getNamespaceURI()) && xPathFragment.getPrefix() == null) {
                        String prefix = namespaceResolver.generatePrefix();
                        String xPath = prefix + Constants.COLON + xPathFragment.getShortName();
                        XPathFragment newFragment = new XPathFragment(xPath);
                        newFragment.setNamespaceURI(defaultNamespaceURI);
                        newFragment.setNextFragment(xPathFragment.getNextFragment());
                        marshalRecord.openStartElement(newFragment, namespaceResolver);
                        isElementOpen = true;
                        marshalRecord.namespaceDeclaration(prefix, defaultNamespaceURI);
                        marshalRecord.predicateAttribute(xPathFragment, namespaceResolver);
                        xPathFragment = newFragment;
                    }
                }
            }

            if (!isElementOpen) {
                 marshalRecord.openStartElement(xPathFragment, namespaceResolver);
            }

            XPathFragment nextFragment = xPathFragment.getNextFragment();
            if (nextFragment != null && nextFragment.isAttribute()) {
                marshalRecord.predicateAttribute(xPathFragment, namespaceResolver);
                marshalRecord.attribute(nextFragment, namespaceResolver, value,schemaType);
                marshalRecord.closeStartElement();
            } else {
                if (xmlField.isTypedTextField()) {
                    updateNamespaces(schemaType, marshalRecord, xmlField);
                }
                marshalRecord.closeStartElement();
                marshalRecord.predicateAttribute(xPathFragment, namespaceResolver);
                marshalRecord.characters(schemaType, value, null, xmlCompositeDirectCollectionMapping.isCDATA());
            }
            marshalRecord.endElement(xPathFragment, namespaceResolver);
            return true;
        } else {
            AbstractNullPolicy nullPolicy = xmlCompositeDirectCollectionMapping.getNullPolicy();
            if (nullPolicy.getMarshalNullRepresentation() != XMLNullRepresentationType.ABSENT_NODE) {
                marshalRecord.openStartElement(xPathFragment, namespaceResolver);
                XPathFragment nextFragment = xPathFragment.getNextFragment();
                nullPolicy.directMarshal(nextFragment, marshalRecord, object, session, namespaceResolver);
                marshalRecord.endElement(xPathFragment, namespaceResolver);
                return true;
            }
        }
        return false;
    }

    @Override
    public DirectCollectionMapping getMapping() {
        return xmlCompositeDirectCollectionMapping;
    }

    @Override
    public boolean isWhitespaceAware() {
        return !xmlCompositeDirectCollectionMapping.getNullPolicy().isNullRepresentedByEmptyNode();
    }

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

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

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

}
