/*******************************************************************************
 * Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/
package org.eclipse.persistence.internal.oxm;

import java.util.ArrayList;

import javax.xml.namespace.QName;

import org.eclipse.persistence.core.sessions.CoreSession;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.DirectMapping;
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;

/**
 * INTERNAL:
 * <p><b>Purpose</b>: This is how the XML Direct Mapping is handled when used
 * with the TreeObjectBuilder.</p>
 */
public class XMLDirectMappingNodeValue extends MappingNodeValue implements NullCapableValue {
    private DirectMapping xmlDirectMapping;

    public XMLDirectMappingNodeValue(DirectMapping xmlDirectMapping) {
        this.xmlDirectMapping = xmlDirectMapping;
    }

    public void setXPathNode(XPathNode xPathNode) {
        super.setXPathNode(xPathNode);
        xmlDirectMapping.getNullPolicy().xPathNode(xPathNode, this);
    }

    public boolean isOwningNode(XPathFragment xPathFragment) {
        return xPathFragment.hasAttribute || xPathFragment.nameIsText;
    }

    public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) {
        return marshal(xPathFragment, marshalRecord, object, session, namespaceResolver, ObjectMarshalContext.getInstance());
    }

    public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
        if (xmlDirectMapping.isReadOnly()) {
            return false;
        }
        Object objectValue = marshalContext.getAttributeValue(object, xmlDirectMapping);
        return this.marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, marshalContext);
    }

    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object objectValue, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
        Object fieldValue = xmlDirectMapping.getFieldValue(objectValue, session, marshalRecord);
        
        // Check for a null value 
        if (null == fieldValue) {
            // Perform marshal operations based on the null policy
            return xmlDirectMapping.getNullPolicy().directMarshal(xPathFragment, marshalRecord, object, session, namespaceResolver);
        } else {            
            QName schemaType = ((Field) xmlDirectMapping.getField()).getSchemaTypeForValue(fieldValue, session);
            XPathFragment groupingFragment = null;    
            boolean isQName = false;
            if(Constants.QNAME_QNAME.equals(schemaType)) {
                //if marshalling a QName, handle grouping elements here in case namespace adjustments need 
                //to happen
                groupingFragment = openGroupingElementsForQName((QName)fieldValue, marshalRecord);
                isQName = true;
            } 
            if(groupingFragment == null) {
                groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
            }
            if (xPathFragment.hasAttribute) {
            	marshalRecord.attribute(xPathFragment, namespaceResolver, fieldValue, schemaType);
                marshalRecord.closeStartGroupingElements(groupingFragment);
            } else {                
                if(((Field) xmlDirectMapping.getField()).getXPathFragment().nameIsText ){
                    XPathNode parentNode = xPathNode.getParent();                  
                    if(parentNode.getAttributeChildren() != null){
                        marshalRecord.forceValueWrapper();
                    }
                }
                
                marshalRecord.closeStartGroupingElements(groupingFragment);           
                marshalRecord.characters(schemaType, fieldValue, null, xmlDirectMapping.isCDATA());                
            }
            if(isQName) {
                //check to see if the last grouping fragment was swapped
                XPathFragment fragment = getLastGroupingFragment();
                if(fragment != groupingFragment) {
                    marshalRecord.endElement(groupingFragment, namespaceResolver);
                    return false;
                }
            }
            return true;
        }
    }

    private XPathFragment getLastGroupingFragment() {
        XPathFragment fragment = ((Field)this.getMapping().getField()).getXPathFragment();
        if(fragment.hasAttribute || fragment.nameIsText) {
            return null;
        }
        while(fragment.getNextFragment() != null) {
            if(fragment.getNextFragment().nameIsText || fragment.getNextFragment().hasAttribute) {
                return fragment;
            }
            fragment = fragment.getNextFragment();
        }
        return fragment;
    }
    private XPathFragment openGroupingElementsForQName(QName fieldValue, MarshalRecord marshalRecord) {
        XPathFragment xPathFragment = null;
        ArrayList<XPathNode> groupingElements = marshalRecord.getGroupingElements();
        NamespaceResolver namespaceResolver = marshalRecord.getNamespaceResolver();
        if((fieldValue.getNamespaceURI() == null || fieldValue.getNamespaceURI().equals(Constants.EMPTY_STRING)) && marshalRecord.getNamespaceResolver().getDefaultNamespaceURI() != null) {
            //In this case, the last grouping element may need to have a new prefix generated. 
            for (int x = 0, groupingElementsSize = groupingElements.size(); x < groupingElementsSize; x++) {
                XPathNode xPathNode = groupingElements.get(x);
                xPathFragment = xPathNode.getXPathFragment();
                if(x == (groupingElements.size() - 1) && namespaceResolver.getDefaultNamespaceURI().equals(xPathFragment.getNamespaceURI()) && xPathFragment.getPrefix() == null) {
                    String prefix = namespaceResolver.generatePrefix();
                    String xPath = prefix +  Constants.COLON + xPathFragment.getShortName(); 
                    XPathFragment newFragment = new XPathFragment(xPath);
                    newFragment.setNamespaceURI(namespaceResolver.getDefaultNamespaceURI());
                    marshalRecord.openStartElement(newFragment, namespaceResolver);
                    marshalRecord.namespaceDeclaration(prefix,  namespaceResolver.getDefaultNamespaceURI());
                    marshalRecord.predicateAttribute(xPathFragment, namespaceResolver);
                    xPathFragment = newFragment;
                } else {
                    marshalRecord.openStartElement(xPathFragment, namespaceResolver);
                    marshalRecord.predicateAttribute(xPathFragment, namespaceResolver);
                    marshalRecord.closeStartElement();
                }
            }
            marshalRecord.setGroupingElement(null);
            
        }
        return xPathFragment;
        
        
    }

    public void attribute(UnmarshalRecord unmarshalRecord, String namespaceURI, String localName, String value) {
        unmarshalRecord.removeNullCapableValue(this);
        Field xmlField = (Field) xmlDirectMapping.getField();
        CoreAbstractSession session = unmarshalRecord.getSession();        
        Object realValue = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, (XMLConversionManager) session.getDatasourcePlatform().getConversionManager(), unmarshalRecord);

        // Perform operations on the object based on the null policy
        Object convertedValue = xmlDirectMapping.getAttributeValue(realValue, session, unmarshalRecord);
        xmlDirectMapping.setAttributeValueInObject(unmarshalRecord.getCurrentObject(), convertedValue);
    }

    public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
        if(unmarshalRecord.isNil() && xmlDirectMapping.getNullPolicy().isNullRepresentedByXsiNil()){
            Object convertedValue = xmlDirectMapping.getAttributeValue(org.eclipse.persistence.oxm.record.XMLRecord.NIL, unmarshalRecord.getSession(), unmarshalRecord);
            unmarshalRecord.setAttributeValue(convertedValue, xmlDirectMapping);
            unmarshalRecord.resetStringBuffer();
            return;
        }        
        
        unmarshalRecord.removeNullCapableValue(this);
        Field xmlField = (Field) xmlDirectMapping.getField();
        if (!xmlField.getLastXPathFragment().nameIsText) {
            return;
        }
        Object value;
        CharSequence unmarshalRecordCharacters = unmarshalRecord.getCharacters();
        if (unmarshalRecordCharacters.length() == 0) {
            value = xmlDirectMapping.getNullValue();
        } else {
            value = unmarshalRecordCharacters.toString();
        }
        unmarshalRecord.resetStringBuffer();
        CoreAbstractSession session = unmarshalRecord.getSession();
        XMLConversionManager xmlConversionManager = (XMLConversionManager) session.getDatasourcePlatform().getConversionManager();
        QName typeQName = unmarshalRecord.getTypeQName(); 
        if (typeQName != null) {
            Class typeClass = xmlField.getJavaClass(typeQName);
            value = xmlConversionManager.convertObject(value, typeClass, typeQName);
        } else {
            value = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, xmlConversionManager, unmarshalRecord);
        }

        Object convertedValue = xmlDirectMapping.getAttributeValue(value, session, unmarshalRecord);
        unmarshalRecord.setAttributeValue(convertedValue, xmlDirectMapping);
    }

    public void setNullValue(Object object, CoreSession session) {
        Object value = xmlDirectMapping.getObjectValue(null, session);
        xmlDirectMapping.setAttributeValueInObject(object, value);
    }

    public boolean isNullCapableValue() {
        if(xmlDirectMapping.getAttributeAccessor().isInstanceVariableAttributeAccessor() && !xmlDirectMapping.hasConverter() && xmlDirectMapping.getNullValue() == null) {
             return false;
        }
        return xmlDirectMapping.getNullPolicy().getIsSetPerformedForAbsentNode();
    }

    public DirectMapping getMapping() {
        return xmlDirectMapping;
    }

    public boolean isWhitespaceAware() {
        return !xmlDirectMapping.getNullPolicy().isNullRepresentedByEmptyNode();
    }

}
