/*******************************************************************************
 * Copyright (c) 2012, 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:
 *     Blaise Doughan - 2.5 - initial implementation
 ******************************************************************************/
package org.eclipse.persistence.internal.oxm.record;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.namespace.QName;

import org.eclipse.persistence.core.descriptors.CoreInheritancePolicy;
import org.eclipse.persistence.internal.core.helper.CoreField;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractRecord;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.Marshaller;
import org.eclipse.persistence.internal.oxm.MediaType;
import org.eclipse.persistence.internal.oxm.Namespace;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.ObjectBuilder;
import org.eclipse.persistence.internal.oxm.Root;
import org.eclipse.persistence.internal.oxm.XPathQName;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;
import org.w3c.dom.Node;

public class AbstractMarshalRecordImpl<
    ABSTRACT_SESSION extends CoreAbstractSession,
    FIELD extends CoreField,
    MARSHALLER extends Marshaller,
    NAMESPACE_RESOLVER extends NamespaceResolver> extends CoreAbstractRecord implements AbstractMarshalRecord<ABSTRACT_SESSION, FIELD, MARSHALLER, NAMESPACE_RESOLVER> {

    protected boolean equalNamespaceResolvers;
    protected boolean hasCustomNamespaceMapper;
    private boolean isXOPPackage;
    private XPathQName leafElementType;
    protected MARSHALLER marshaller;
    protected boolean namespaceAware = true;
    protected NAMESPACE_RESOLVER namespaceResolver;
    private Object owningObject;
    private AbstractMarshalRecord<ABSTRACT_SESSION, FIELD, MARSHALLER, NAMESPACE_RESOLVER> realRecord;
    protected ABSTRACT_SESSION session;

    public AbstractMarshalRecordImpl(AbstractMarshalRecord realRecord) {
        this.realRecord = realRecord;
    }

    @Override
    public List addExtraNamespacesToNamespaceResolver(Descriptor descriptor,
            CoreAbstractSession session, boolean allowOverride,
            boolean ignoreEqualResolvers) {
        if (equalNamespaceResolvers && !ignoreEqualResolvers) {
            return null;
        }

        org.eclipse.persistence.internal.oxm.NamespaceResolver descriptorNamespaceResolver = descriptor.getNamespaceResolver();
        if(null == descriptorNamespaceResolver || !descriptorNamespaceResolver.hasPrefixesToNamespaces()) {
            return null;
        }
        Map<String, String> prefixesToNamespaces = descriptorNamespaceResolver.getPrefixesToNamespaces();
        if(prefixesToNamespaces.size() == 0) {
            return null;
        }
        List returnList = new ArrayList(prefixesToNamespaces.size());
        org.eclipse.persistence.internal.oxm.NamespaceResolver marshalRecordNamespaceResolver = namespaceResolver;
        for(Entry<String, String> entry: prefixesToNamespaces.entrySet()) {

            //if isn't already on a parentadd namespace to this element
            String prefix = marshalRecordNamespaceResolver.resolveNamespaceURI(entry.getValue());

            if (prefix == null || prefix.length() == 0) {
                //if there is no prefix already declared for this uri in the nr add this one
                //unless that prefix is already bound to another namespace uri
                prefix = entry.getKey();
                if(hasCustomNamespaceMapper) {
                    String newPrefix = getMarshaller().getNamespacePrefixMapper().getPreferredPrefix(entry.getValue(), prefix, true);
                    if(newPrefix != null && !(newPrefix.length() == 0)) {
                        prefix = newPrefix;
                    }
                }
                String uri = marshalRecordNamespaceResolver.resolveNamespacePrefix(prefix);
                if(hasCustomNamespaceMapper || allowOverride || uri == null || uri.length() == 0) {
                    //if this uri is unknown, the cutom mapper will return the preferred prefix for this uri
                    marshalRecordNamespaceResolver.put(entry.getKey(), entry.getValue());
                    returnList.add(new Namespace(prefix, entry.getValue()));
                }
            } else if(allowOverride) {
                //if overrides are allowed, add the prefix if the URI is different
                if (!prefix.equals(entry.getKey()) && !hasCustomNamespaceMapper) {
                    //if prefix exists for uri but is different then add this
                    //unless using a custom namespace prefix mapper. Then prefix is expected to be different
                    marshalRecordNamespaceResolver.put(entry.getKey(), entry.getValue());
                    returnList.add(new Namespace(entry.getKey(), entry.getValue()));
                }
            }
        }
        return returnList;
    }

    public boolean addXsiTypeAndClassIndicatorIfRequired(Descriptor descriptor, Descriptor referenceDescriptor, Field xmlField, boolean isRootElement) {
        ObjectBuilder objectBuilder = (ObjectBuilder) descriptor.getObjectBuilder();
        boolean xsiTypeIndicatorField = objectBuilder.isXsiTypeIndicatorField();

        if(objectBuilder.addClassIndicatorFieldToRow(this)) {
            return true;
        }

        

        QName leafType = null;
        if (xmlField != null) {
            leafType = xmlField.getLeafElementType();

            XMLSchemaReference xmlRef = descriptor.getSchemaReference();
            if (xmlRef != null) {
                if (leafType == null) {
                    if (xmlRef.getType() == XMLSchemaReference.ELEMENT) {
                        return false;
                    }
                    if (referenceDescriptor == null) {
                        writeXsiTypeAttribute(descriptor, xmlRef, isRootElement);
                        return true;
                    }
                } else if (((xmlRef.getType() == XMLSchemaReference.COMPLEX_TYPE) || (xmlRef.getType() == XMLSchemaReference.SIMPLE_TYPE)) && xmlRef.getSchemaContext() != null && xmlRef.isGlobalDefinition()) {
                    QName ctxQName = xmlRef.getSchemaContextAsQName(descriptor.getNamespaceResolver());
                    if (!ctxQName.equals(leafType)) {
                        writeXsiTypeAttribute(descriptor, xmlRef, isRootElement);
                        return true;
                    }
                }
            }
        }

        if (referenceDescriptor != null && referenceDescriptor == descriptor) {
            return false;
        }
        if (descriptor.hasInheritance() && !descriptor.getInheritancePolicy().isRootParentDescriptor()) {
            CoreInheritancePolicy inheritancePolicy = descriptor.getInheritancePolicy();
            Field indicatorField = (Field) inheritancePolicy.getClassIndicatorField();
            if (indicatorField != null && xsiTypeIndicatorField) {
                Object classIndicatorValueObject = inheritancePolicy.getClassIndicatorMapping().get(descriptor.getJavaClass());
                String classIndicatorUri = null;
                String classIndicatorLocal= null;
                String classIndicatorPrefix= null;
                if (classIndicatorValueObject instanceof QName) {
                    QName classIndicatorQName = (QName) classIndicatorValueObject;
                    classIndicatorUri = classIndicatorQName.getNamespaceURI();
                    classIndicatorLocal = classIndicatorQName.getLocalPart();
                    classIndicatorPrefix = classIndicatorQName.getPrefix();
                } else {
                    String classIndicatorValue = (String) inheritancePolicy.getClassIndicatorMapping().get(descriptor.getJavaClass());
                    int nsindex = classIndicatorValue.indexOf(Constants.COLON);
                    String prefix = null;
                    if (nsindex != -1) {
                        classIndicatorLocal = classIndicatorValue.substring(nsindex + 1);
                        prefix = classIndicatorValue.substring(0, nsindex);
                    } else {
                        classIndicatorLocal = classIndicatorValue;
                    }
                    classIndicatorUri = descriptor.getNonNullNamespaceResolver().resolveNamespacePrefix(prefix);
                }
                if(leafType == null 
                        || isRootElement && marshaller.getMediaType().isApplicationJSON() && !marshaller.isIncludeRoot() 
                        || !(leafType.getLocalPart().equals(classIndicatorLocal))
                        || (classIndicatorUri == null && (leafType.getNamespaceURI() != null && leafType.getNamespaceURI().length() >0))
                        || (classIndicatorUri != null && !classIndicatorUri.equals(leafType.getNamespaceURI()))
                       ){
                    if (inheritancePolicy.hasClassExtractor()) {
                        objectBuilder.addClassIndicatorFieldToRow(this);
                    } else {
                        writeXsiTypeAttribute(descriptor, classIndicatorUri, classIndicatorLocal,classIndicatorPrefix, isRootElement);
                    }
                    return true;
                }
                return false;
            }

        }
        return false;
    }

    /**
     * INTERNAL
     * @since EclipseLink 2.5.0
     */
   public boolean addXsiTypeAndClassIndicatorIfRequired(Descriptor descriptor, Descriptor referenceDescriptor, Field xmlField,
           Object originalObject, Object obj, boolean wasXMLRoot, boolean isRootElement) {
        if (wasXMLRoot) {
            XMLSchemaReference xmlRef = descriptor.getSchemaReference();

            if (descriptor != null) {
                Root xr = (Root) originalObject;

                if (xmlRef == null) {
                    return false;
                }
            
	    if (xr.getDeclaredType() != null && xr.getDeclaredType() == xr.getObject().getClass()) {
                    return false;
                }

                String xmlRootLocalName = xr.getLocalName();
                String xmlRootUri = xr.getNamespaceURI();

                XPathQName qName = new XPathQName(xmlRootUri, xmlRootLocalName, namespaceAware);
                Descriptor xdesc = marshaller.getContext().getDescriptor(qName);
                if (xdesc != null) {
                    boolean writeTypeAttribute = xdesc.getJavaClass() != descriptor.getJavaClass();
                    if (writeTypeAttribute) {
                        writeXsiTypeAttribute(descriptor, xmlRef, isRootElement);
                        return true;
                    }
                    return false;

                }

                boolean writeTypeAttribute = true;
                int tableSize = descriptor.getTableNames().size();
                for (int i = 0; i < tableSize; i++) {
                    if (!writeTypeAttribute) {
                        return false;
                    }
                    String defaultRootQualifiedName = (String) descriptor.getTableNames().get(i);
                    if (defaultRootQualifiedName != null) {
                        String defaultRootLocalName = null;
                        String defaultRootUri = null;
                        int colonIndex = defaultRootQualifiedName.indexOf(Constants.COLON);
                        if (colonIndex > 0) {
                            String defaultRootPrefix = defaultRootQualifiedName.substring(0, colonIndex);
                            defaultRootLocalName = defaultRootQualifiedName.substring(colonIndex + 1);
                            if (descriptor.getNamespaceResolver() != null) {
                                defaultRootUri = descriptor.getNamespaceResolver().resolveNamespacePrefix(defaultRootPrefix);
                            }
                        } else {
                            defaultRootLocalName = defaultRootQualifiedName;
                        }

                        if (xmlRootLocalName != null) {
                            if ((((defaultRootLocalName == null) && (xmlRootLocalName == null)) || (defaultRootLocalName.equals(xmlRootLocalName)))
                                && (((defaultRootUri == null) && (xmlRootUri == null)) || ((xmlRootUri != null) && (defaultRootUri != null) && (defaultRootUri.equals(xmlRootUri))))) {
                                // if both local name and uris are equal then don't need to write type attribute
                                return false;
                            }
                        }
                    } else {
                        // no default rootElement was set
                        // if xmlRootName = null then writeTypeAttribute = false
                        if (xmlRootLocalName == null) {
                            return false;
                        }
                    }
                }
                if (writeTypeAttribute && xmlRef != null) {
                    writeXsiTypeAttribute(descriptor, xmlRef, isRootElement);
                    return true;
                }
            }
            return false;
        } else {
            return addXsiTypeAndClassIndicatorIfRequired(descriptor, referenceDescriptor, xmlField, isRootElement);
        }
    }

    public void attribute(String namespaceURI, String localName,
            String qualifiedName, String value) {
        if(null != realRecord) {
            realRecord.attribute(namespaceURI, localName, qualifiedName, value);
        }
    }

    @Override
    public void attributeWithoutQName(String namespaceURI, String localName,
            String prefix, String value) {
        String qualifiedName = localName;
        if(prefix != null && prefix.length() >0){
            qualifiedName = prefix + getNamespaceSeparator() + qualifiedName;
        }
        attribute(namespaceURI, localName, qualifiedName, value);
    }

    @Override
    public Node getDOM() {
        // TODO Auto-generated method stub
        throw new UnsupportedOperationException();
    }

    public XPathQName getLeafElementType() {
        return leafElementType;
    }

    @Override
    public MARSHALLER getMarshaller() {
        return marshaller;
    }

    @Override
    public NAMESPACE_RESOLVER getNamespaceResolver() {
        return namespaceResolver;
    }

    @Override
    public char getNamespaceSeparator() {
        return Constants.COLON;
    }

    @Override
    public Object getOwningObject() {
        return owningObject;
    }

    @Override
    public ABSTRACT_SESSION getSession() {
        return session;
    }

    @Override
    public boolean hasCustomNamespaceMapper() {
        return hasCustomNamespaceMapper;
    }

    @Override
    public boolean hasEqualNamespaceResolvers() {
        return equalNamespaceResolvers;
    }

    /**
     * Determine if namespaces will be considered during marshal/unmarshal operations.
     */
    @Override
    public boolean isNamespaceAware() {
        return namespaceAware;
    }

    @Override
    public boolean isXOPPackage() {
        return isXOPPackage;
    }

    @Override
    public void namespaceDeclaration(String prefix, String typeUri) {
        if(realRecord != null) {
            realRecord.namespaceDeclaration(prefix, typeUri);
            return;
        }
        throw new UnsupportedOperationException();
    }

    @Override
    public Object put(FIELD field, Object object) {
        if(null != realRecord) {
            return realRecord.put(field, object);
        }
        throw new UnsupportedOperationException();
    }

    @Override
    public void removeExtraNamespacesFromNamespaceResolver(List<Namespace> extraNamespaces, CoreAbstractSession session) {
        if (extraNamespaces == null){
          return;
        }

         for (int i = 0; i < extraNamespaces.size(); i++) {
             Namespace nextExtraNamespace = (Namespace)extraNamespaces.get(i);
             String uri = namespaceResolver.resolveNamespacePrefix(nextExtraNamespace.getPrefix());
             if ((uri != null) && uri.equals(nextExtraNamespace.getNamespaceURI())) {
                namespaceResolver.removeNamespace(nextExtraNamespace.getPrefix());
             }
         }
     }

    @Override
    public String resolveNamespacePrefix(String prefix) {
        return null;
    }

    @Override
    public void setCustomNamespaceMapper(boolean customNamespaceMapper) {
        this.hasCustomNamespaceMapper = customNamespaceMapper;
    }

    @Override
    public void setEqualNamespaceResolvers(boolean equalNRs) {
        this.equalNamespaceResolvers = equalNRs;
    }

    @Override
    public void setLeafElementType(QName type) {
        if(type != null){
            setLeafElementType(new XPathQName(type, isNamespaceAware()));
        }
    }

    @Override
    public void setLeafElementType(XPathQName type) {
        leafElementType = type;
    }

    @Override
    public void setMarshaller(MARSHALLER marshaller) {
        this.marshaller = marshaller;
        if(marshaller != null){
            MediaType mediaType = marshaller.getMediaType();
            if(marshaller.getNamespacePrefixMapper() != null){
                namespaceAware = true;              
            }else{
                namespaceAware = mediaType.isApplicationXML();
            }
        }
    }

    @Override
    public void setNamespaceResolver(NAMESPACE_RESOLVER namespaceResolver) {
        this.namespaceResolver = namespaceResolver;
    }

    @Override
    public void setOwningObject(Object owningObject) {
        this.owningObject = owningObject;
    }

    @Override
    public void setSession(ABSTRACT_SESSION session) {
        this.session = session;
    }

    @Override
    public void setXOPPackage(boolean isXOPPackage) {
        this.isXOPPackage = isXOPPackage;
    }

    @Override
    public void writeXsiTypeAttribute(Descriptor descriptor, String typeUri,
            String typeLocal, String typePrefix, boolean addToNamespaceResolver) {
        if (typeLocal == null){
            return;
        }
        String typeValue = typeLocal;
        if(isNamespaceAware() && typeUri != null && !typeUri.equals(Constants.EMPTY_STRING) && !typeUri.equals(namespaceResolver.getDefaultNamespaceURI())){
            String prefix = namespaceResolver.resolveNamespaceURI(typeUri);
            if(prefix != null && !prefix.equals(Constants.EMPTY_STRING)){
                typeValue = prefix + getNamespaceSeparator() + typeValue;
            } else if (typeUri.equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
                prefix = namespaceResolver.generatePrefix(Constants.SCHEMA_PREFIX);
                typeValue = prefix + getNamespaceSeparator() + typeValue;
                namespaceDeclaration(prefix, typeUri);
             
            } else if (typePrefix != null && !typePrefix.equals(Constants.EMPTY_STRING)){
                String existingUri = namespaceResolver.resolveNamespacePrefix(typePrefix);
                if(existingUri != null){
                    prefix = namespaceResolver.generatePrefix();
                }else{
                    prefix = typePrefix;   
                }               
                typeValue = prefix + getNamespaceSeparator() + typeValue;
                namespaceDeclaration(prefix, typeUri);
            }else{
                prefix = namespaceResolver.generatePrefix();
                typeValue = prefix + getNamespaceSeparator() + typeValue;
                namespaceDeclaration(prefix, typeUri);

            }
        }
        
        String xsiPrefix = null;
        if(isNamespaceAware()){
            xsiPrefix = namespaceResolver.resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
            if (xsiPrefix == null) {
                xsiPrefix = namespaceResolver.generatePrefix(Constants.SCHEMA_INSTANCE_PREFIX);
                namespaceDeclaration(xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
                if(addToNamespaceResolver){
                    namespaceResolver.put(xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
                }
            }
        }
        attributeWithoutQName(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_TYPE_ATTRIBUTE, xsiPrefix, typeValue);
    }

    @Override
    public void writeXsiTypeAttribute(Descriptor xmlDescriptor, XMLSchemaReference xmlRef, boolean addToNamespaceResolver) {
        QName contextAsQName = xmlRef.getSchemaContextAsQName();
        
        if(contextAsQName == null){
            contextAsQName = xmlRef.getSchemaContextAsQName(namespaceResolver);
        }
        if (contextAsQName != null) {
            writeXsiTypeAttribute(xmlDescriptor, contextAsQName.getNamespaceURI(), contextAsQName.getLocalPart(), null, addToNamespaceResolver);
        }
    }

}
