/*
 * 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:
//     Denise Smith - 2.5.1 - Initial Implementation
package org.eclipse.persistence.internal.oxm;

import java.util.List;

import javax.xml.namespace.QName;

import org.eclipse.persistence.core.mappings.CoreAttributeAccessor;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.CompositeObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.DirectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.mappings.UnmarshalKeepAsElementPolicy;
import org.eclipse.persistence.internal.oxm.mappings.VariableXPathObjectMapping;
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

public abstract class XMLVariableXPathMappingNodeValue extends XMLRelationshipMappingNodeValue{


    /**
     * INTERNAL:
     * @param xPathFragment
     * @return
     */
     @Override
    public boolean isOwningNode(XPathFragment xPathFragment) {
            return null == xPathFragment;
     }

    @Override
    protected Descriptor findReferenceDescriptor(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts, Mapping mapping, UnmarshalKeepAsElementPolicy policy) {
       return (Descriptor)mapping.getReferenceDescriptor();
    }

     @Override
    public void attribute(UnmarshalRecord unmarshalRecord, String namespaceURI, String localName, String value) {
            Descriptor referenceDescriptor = (Descriptor) getMapping().getReferenceDescriptor();
            ObjectBuilder treeObjectBuilder = (ObjectBuilder) referenceDescriptor.getObjectBuilder();
            MappingNodeValue textMappingNodeValue = (MappingNodeValue) treeObjectBuilder.getRootXPathNode().getTextNode().getNodeValue();
            Mapping textMapping = textMappingNodeValue.getMapping();
            Object childObject = referenceDescriptor.getInstantiationPolicy().buildNewInstance();
            if(textMapping.isAbstractDirectMapping()) {
                DirectMapping xmlDirectMapping = (DirectMapping) textMappingNodeValue.getMapping();
                Field xmlField = (Field) xmlDirectMapping.getField();
                Object realValue = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, (ConversionManager) unmarshalRecord.getSession().getDatasourcePlatform().getConversionManager(), unmarshalRecord);
                Object convertedValue = xmlDirectMapping.getAttributeValue(realValue, unmarshalRecord.getSession(), unmarshalRecord);
                xmlDirectMapping.setAttributeValueInObject(childObject, convertedValue);
            } else {
                Object oldChildObject = unmarshalRecord.getCurrentObject();
                CompositeObjectMapping nestedXMLCompositeObjectMapping = (CompositeObjectMapping) textMappingNodeValue.getMapping();
                unmarshalRecord.setCurrentObject(childObject);
                textMappingNodeValue.attribute(unmarshalRecord, namespaceURI, localName, value);
                unmarshalRecord.setCurrentObject(oldChildObject);
            }
            setXPathInObject(namespaceURI, localName, childObject);
            setOrAddAttributeValue(unmarshalRecord, childObject, null, null);
        }

    @Override
    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object value, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
        if (null == value) {
            return false;
        }

        Object originalValue = value;
        VariableXPathObjectMapping mapping = this.getMapping();
        Descriptor descriptor = (Descriptor)mapping.getReferenceDescriptor();

        if(descriptor.hasInheritance()){
              Class objectValueClass = value.getClass();
               if(!(objectValueClass == descriptor.getJavaClass())){
                   descriptor = (Descriptor) session.getDescriptor(objectValueClass);
               }
        }

        Marshaller marshaller = marshalRecord.getMarshaller();
        ObjectBuilder objectBuilder = (ObjectBuilder)descriptor.getObjectBuilder();
        List extraNamespaces = objectBuilder.addExtraNamespacesToNamespaceResolver(descriptor, marshalRecord, session, true, true);
        //Change to get the value from the object
        String defaultRootElementString = descriptor.getDefaultRootElement();

        marshalRecord.beforeContainmentMarshal(value);
        XPathFragment rootFragment = mapping.getXPathFragmentForValue(value, marshalRecord.getNamespaceResolver(), marshalRecord.isNamespaceAware(), marshalRecord.getNamespaceSeparator());

        XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
        if(mapping.isAttribute()){
               ObjectBuilder tob = (ObjectBuilder) mapping.getReferenceDescriptor().getObjectBuilder();
                MappingNodeValue textMappingNodeValue = (MappingNodeValue) tob.getRootXPathNode().getTextNode().getMarshalNodeValue();
                Mapping textMapping = textMappingNodeValue.getMapping();
                if(textMapping.isAbstractDirectMapping()) {
                    DirectMapping xmlDirectMapping = (DirectMapping) textMapping;
                    Object fieldValue = xmlDirectMapping.getFieldValue(xmlDirectMapping.valueFromObject(value, xmlDirectMapping.getField(), session), session, marshalRecord);
                    QName schemaType = ((Field) xmlDirectMapping.getField()).getSchemaTypeForValue(fieldValue, session);
                    marshalRecord.attribute(rootFragment, namespaceResolver, fieldValue, schemaType);
                    //marshalRecord.closeStartGroupingElements(groupingFragment);
                    return true;
                } else {
                    return textMappingNodeValue.marshalSingleValue(rootFragment, marshalRecord, value, textMapping.getAttributeValueFromObject(value), session, namespaceResolver, marshalContext);
                }
        }else{
            marshalRecord.closeStartGroupingElements(groupingFragment);
        getXPathNode().startElement(marshalRecord, rootFragment, object, session, marshalRecord.getNamespaceResolver(), objectBuilder, value);
        writeExtraNamespaces(extraNamespaces, marshalRecord, session);

        marshalRecord.addXsiTypeAndClassIndicatorIfRequired(descriptor, (Descriptor)mapping.getReferenceDescriptor(), (Field)mapping.getField(), originalValue, value, false, false);
        objectBuilder.buildRow(marshalRecord, value, session, marshaller, null);
        marshalRecord.afterContainmentMarshal(object, value);
        marshalRecord.endElement(rootFragment, namespaceResolver);
        marshalRecord.removeExtraNamespacesFromNamespaceResolver(extraNamespaces, session);
        }
        return true;
    }

    @Override
    public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
        UnmarshalRecord childRecord = unmarshalRecord.getChildRecord();
        if(childRecord != null){
            Object childObject = childRecord.getCurrentObject();
            String localName = xPathFragment.getLocalName();

            setXPathInObject(xPathFragment.getNamespaceURI(), localName, childObject);

            childObject = getMapping().convertDataValueToObjectValue(childObject, unmarshalRecord.getSession(), unmarshalRecord.getUnmarshaller());
            setOrAddAttributeValue(unmarshalRecord, childObject, xPathFragment, null);
            unmarshalRecord.setChildRecord(null);
        } else {
             unmarshalRecord.resetStringBuffer();
        }
    }

    @Override
    public abstract VariableXPathObjectMapping getMapping();

    public void setXPathInObject(String uri, String localName, Object childObject) {
        CoreAttributeAccessor variableAttributeAccessor = this.getMapping().getVariableAttributeAccessor();
        if(!variableAttributeAccessor.isWriteOnly()){
        Object value = null;
         if(getMapping().getVariableAttributeAccessor().getAttributeClass() == CoreClassConstants.QNAME){
                 if(uri != null && uri.length() > 0) {
                     value =  new QName(uri, localName);
                 }else{
                     value =  new QName( localName);
                 }
            }else{
                value = localName;
            }

            variableAttributeAccessor.setAttributeValueInObject(childObject, value);
        }
    }

    @Override
    public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) {
           try {
            processChild(xPathFragment, unmarshalRecord, atts, (Descriptor) getMapping().getReferenceDescriptor(), getMapping());
        } catch (SAXException e) {
            throw XMLMarshalException.unmarshalException(e);
        }
         return true;
     }

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

}
