/*******************************************************************************
 * 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:
 *     David McCann - 2.5.0 - Sept.14, 2012 - Initial Implementation
 ******************************************************************************/
package org.eclipse.persistence.tools.dbws;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.jaxb.xmlmodel.JavaType;
import org.eclipse.persistence.jaxb.xmlmodel.JavaType.JavaAttributes;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAbstractNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAccessType;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAttribute;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElement;
import org.eclipse.persistence.jaxb.xmlmodel.XmlIsSetNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlMarshalNullRepresentation;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNsForm;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.JavaTypes;
import org.eclipse.persistence.jaxb.xmlmodel.XmlSchema;
import org.eclipse.persistence.jaxb.xmlmodel.XmlSchema.XmlNs;
import org.eclipse.persistence.jaxb.xmlmodel.XmlSchemaType;
import org.eclipse.persistence.jaxb.xmlmodel.XmlType;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.mappings.XMLBinaryDataMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeDirectCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.XMLMapping;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.IsSetNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.NullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType;

import static org.eclipse.persistence.oxm.XMLConstants.EMPTY_STRING;
import static org.eclipse.persistence.tools.dbws.Util.DOT;
import static org.eclipse.persistence.tools.dbws.Util.XML_MIME_PREFIX;

/**
 * This class is responsible for generating one or more EclipseLink XmlBindings
 * objects based on a given list of XMLDescriptors.
 * 
 */
public class XmlBindingsGenerator {
    public static final String SIMPLE_XML_FORMAT_PKG = "org.eclipse.persistence.internal.xr.sxf"; 
    public static final String DATAHANDLER_CLASSNAME = "javax.activation.DataHandler";

    /**
     * Generate one or more XmlBindings based on a given list of
     * XML Descriptor instances.
     * 
     */
    public static List<XmlBindings> generateXmlBindings(List<ClassDescriptor> descriptors) {
        // group the descriptors by package name
        HashMap<String, List<XMLDescriptor>> descriptorMap = new HashMap<String, List<XMLDescriptor>>();
        for (ClassDescriptor cdesc : descriptors) {
            XMLDescriptor xdesc = (XMLDescriptor) cdesc;
            String packageName = getPackageName(xdesc.getJavaClassName());
            // don't process the simple-xml-format descriptor
            if (packageName.equals(SIMPLE_XML_FORMAT_PKG)) {
                continue;
            }
            List<XMLDescriptor> descriptorList = descriptorMap.get(packageName);
            if (descriptorList == null) {
                descriptorList = new ArrayList<XMLDescriptor>();
                descriptorMap.put(packageName, descriptorList);
            }
            descriptorList.add(xdesc);
        }

        List<XmlBindings> bindingsList = new ArrayList<XmlBindings>();
        // generate an XmlBindings for each package
        for (String pkg : descriptorMap.keySet()) {
            List<XMLDescriptor> xdescList = descriptorMap.get(pkg);
            
            XmlBindings xmlBindings = generateXmlBindings(pkg, xdescList);
            if (xmlBindings != null) {
                bindingsList.add(xmlBindings);
            }
        }
        return bindingsList;
    }
    
    /**
     * Generate an XmlBindings instance based on a list of XML descriptors.
     * 
     * OXM metadata files are processed on a per package basis, hence it is
     * assumed that the given list of descriptors are from the same package.
     * 
     */
    public static XmlBindings generateXmlBindings(String packageName, List<XMLDescriptor> descriptors) {
        String defaultNamespace = null;
        Map<String, String> prefixMap = new HashMap<String, String>();
        
        JavaTypes jTypes = new JavaTypes();
        for (XMLDescriptor xdesc : descriptors) {
            // get xml-schema info from one of the descriptors, and add prefix
            // mappings to the map
            if (xdesc.getNamespaceResolver() != null) {
                if (defaultNamespace == null) {
                    defaultNamespace = xdesc.getNamespaceResolver().getDefaultNamespaceURI();
                }
                Map<String, String> preMap = xdesc.getNamespaceResolver().getPrefixesToNamespaces();
                for (String pfx : preMap.keySet()) {
                    // ignore mime prefix/url for now
                    if (!pfx.equals(XML_MIME_PREFIX)) {
                        prefixMap.put(pfx, preMap.get(pfx));
                    }
                }
            }
            // generate a JavaType instance for the XML descriptor
            jTypes.getJavaType().add(generateJavaType(xdesc));
        }
        
        XmlBindings xmlBindings = null;
        // if there are no JavaTypes, there's nothing to do
        if (jTypes.getJavaType().size() > 0) {
            xmlBindings = new XmlBindings();
            xmlBindings.setJavaTypes(jTypes);
            xmlBindings.setPackageName(packageName);
            // handle XmlSchema
            if (defaultNamespace != null || !prefixMap.isEmpty()) {
                XmlSchema xSchema = new XmlSchema();
                xSchema.setNamespace(defaultNamespace == null ? EMPTY_STRING : defaultNamespace);
                xSchema.setElementFormDefault(XmlNsForm.QUALIFIED);
                // handle XmlNs
                if (!prefixMap.isEmpty()) {
                    XmlNs xmlNs;
                    for (String pfx : prefixMap.keySet()) {
                        xmlNs = new XmlNs();
                        xmlNs.setNamespaceUri(prefixMap.get(pfx));
                        xmlNs.setPrefix(pfx);
                        xSchema.getXmlNs().add(xmlNs);
                    }
                }
                xmlBindings.setXmlSchema(xSchema);
            }
        }
        return xmlBindings;
    }

    /**
     * Process a given XMLDescriptor and return a JavaType instance.
     * 
     */
    protected static JavaType generateJavaType(XMLDescriptor xdesc) {
        String defaultNamespace = null;
        if (xdesc.getNamespaceResolver() != null) {
            defaultNamespace = xdesc.getNamespaceResolver().getDefaultNamespaceURI();
        }
        String schemaContext = null;
        if (xdesc.getSchemaReference() != null) {
            schemaContext = xdesc.getSchemaReference().getSchemaContext();
        }
        
        JavaType jType = new JavaType();
        jType.setName(getClassName(xdesc.getJavaClassName()));
        jType.setXmlAccessorType(XmlAccessType.FIELD);
        
        // handle XmlType
        if (schemaContext != null) {
            XmlType xType = new XmlType();
            xType.setName(schemaContext.substring(1, schemaContext.length()));
            if (defaultNamespace != null) {
                xType.setNamespace(defaultNamespace);
            }
            jType.setXmlType(xType);
        }        
        // handle XmlRootElement
        XmlRootElement xmlRootElt = new XmlRootElement();
        xmlRootElt.setName(xdesc.getDefaultRootElement());
        if (defaultNamespace != null) {
            xmlRootElt.setNamespace(defaultNamespace);
        }
        jType.setXmlRootElement(xmlRootElt);
        jType.setJavaAttributes(new JavaAttributes());
        // generate an XmlAttribute or XmlElement for each mapping
        for (Iterator<DatabaseMapping> xmapIt = xdesc.getMappings().iterator(); xmapIt.hasNext();) {
            XMLMapping xMap = (XMLMapping) xmapIt.next();
            if (((XMLField) xMap.getField()).getXPathFragment().isAttribute()) {
                JAXBElement<XmlAttribute> jAtt = generateXmlAttribute(xMap);
                if (jAtt != null) {
                    jType.getJavaAttributes().getJavaAttribute().add(jAtt);
                }
            } else {
                JAXBElement<XmlElement> jElt = generateXmlElement(xMap);
                if (jElt != null) {
                    jType.getJavaAttributes().getJavaAttribute().add(jElt);
                }
            }
        }
        return jType;
    }

    /**
     * Process a given XMLMapping and return a JAXBElement<XmlAttribute>.
     * 
     * Expected mappings are:
     * <ul>
     * <li>org.eclipse.persistence.oxm.mappings.XMLBinaryDataMapping
     * <li>org.eclipse.persistence.oxm.mappings.XMLCompositeDirectCollectionMapping
     * <li>org.eclipse.persistence.oxm.mappings.XMLDirectMapping
     * </ul>
     */
    protected static JAXBElement<XmlAttribute> generateXmlAttribute(XMLMapping xmap) {
        XmlAttribute xAtt = null;
        if (xmap instanceof XMLDirectMapping) {
            // could be an XMLBinaryDataMapping instance
            if (xmap instanceof XMLBinaryDataMapping) {
                xAtt = processXMLBinaryDataMappingAttribute((XMLBinaryDataMapping) xmap);
            } else {
                xAtt = processXMLDirectMappingAttribute((XMLDirectMapping) xmap);
            }
        } else if (xmap instanceof XMLCompositeDirectCollectionMapping) {
            xAtt = processXMLCompositeDirectCollectionMappingAttribute((XMLCompositeDirectCollectionMapping) xmap);
        }
        if (xAtt == null) {
            return null;
        }
        return new JAXBElement<XmlAttribute>(new QName("http://www.eclipse.org/eclipselink/xsds/persistence/oxm", "xml-attribute"), XmlAttribute.class, xAtt);
    }
    
    /**
     * Process a given XMLMapping and return a JAXBElement<XmlElement>.
     * 
     * Expected mappings are:
     * <ul>
     * <li>org.eclipse.persistence.oxm.mappings.XMLBinaryDataMapping
     * <li>org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping
     * <li>org.eclipse.persistence.oxm.mappings.XMLCompositeDirectCollectionMapping
     * <li>org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping
     * <li>org.eclipse.persistence.oxm.mappings.XMLDirectMapping
     * </ul>
     */
    protected static JAXBElement<XmlElement> generateXmlElement(XMLMapping xmap) {
        XmlElement xElt = null;
        if (xmap instanceof XMLCompositeObjectMapping) {
            xElt = processXMLCompositeObjectMapping((XMLCompositeObjectMapping) xmap);
        } else if (xmap instanceof XMLCompositeCollectionMapping) {
            xElt = processXMLCompositeCollectionMapping((XMLCompositeCollectionMapping) xmap);
        } else if (xmap instanceof XMLCompositeDirectCollectionMapping) {
            xElt = processXMLCompositeDirectCollectionMapping((XMLCompositeDirectCollectionMapping) xmap);
        } else if (xmap instanceof XMLDirectMapping) {
            // could be an XMLBinaryDataMapping instance
            if (xmap instanceof XMLBinaryDataMapping) {
                xElt = processXMLBinaryDataMapping((XMLBinaryDataMapping) xmap);
            } else {
                xElt = processXMLDirectMapping((XMLDirectMapping) xmap);
            }
        }
        if (xElt == null) {
            return null;
        }
        return new JAXBElement<XmlElement>(new QName("http://www.eclipse.org/eclipselink/xsds/persistence/oxm", "xml-element"), XmlElement.class, xElt);
    }

    /**
     * Process a given XMLMapping and return an XmlAttribute.
     * 
     */
    protected static XmlAttribute processXMLMapping(XMLField xfld, String attName, String xpath, String attClassification, 
            AbstractNullPolicy nullPolicy, String containerName, boolean inlineBinary, boolean isSWARef, String mimeType) {

        XmlAttribute xAtt = new XmlAttribute();
        xAtt.setJavaAttribute(attName);
        xAtt.setXmlPath(xpath);
        if (xfld.isRequired()) {
            xAtt.setRequired(true);
        }
        if (inlineBinary) {
            xAtt.setXmlInlineBinaryData(true);
        }
        if (isSWARef) {
            xAtt.setXmlAttachmentRef(true);
        }
        if (attClassification != null) {
            xAtt.setType(attClassification);
        }
        if (containerName != null) {
            xAtt.setContainerType(containerName);
        }
        if (mimeType != null) {
            xAtt.setXmlMimeType(mimeType);
        }
        QName schemaType = xfld.getSchemaType();
        if (schemaType != null) {
            XmlSchemaType xSchemaType = new XmlSchemaType();
            xSchemaType.setName(schemaType.getLocalPart());
            xAtt.setXmlSchemaType(xSchemaType);
        }
        if (!isDefaultNullPolicy(nullPolicy)) {
            XmlAbstractNullPolicy xmlNullPolicy;
            
            if (nullPolicy instanceof NullPolicy) {
                xmlNullPolicy = new XmlNullPolicy();
                ((XmlNullPolicy) xmlNullPolicy).setIsSetPerformedForAbsentNode(nullPolicy.getIsSetPerformedForAbsentNode());
            } else {
                xmlNullPolicy = new XmlIsSetNullPolicy();
            }
            xmlNullPolicy.setEmptyNodeRepresentsNull(nullPolicy.isNullRepresentedByEmptyNode());
            xmlNullPolicy.setXsiNilRepresentsNull(nullPolicy.isNullRepresentedByXsiNil());
            xmlNullPolicy.setNullRepresentationForXml(XmlMarshalNullRepresentation.fromValue(nullPolicy.getMarshalNullRepresentation().toString()));

            xAtt.setXmlAbstractNullPolicy(new JAXBElement<XmlAbstractNullPolicy>(new QName("http://www.eclipse.org/eclipselink/xsds/persistence/oxm", "xml-null-policy"), XmlAbstractNullPolicy.class, xmlNullPolicy));
        }
        return xAtt;
    }

    /**
     * Process a given XMLBinaryDataMapping and return an XmlAttribute.
     * 
     */
    protected static XmlAttribute processXMLBinaryDataMappingAttribute(XMLBinaryDataMapping xmap) {
        // JAXB expects a DataHandler in the object model for SwaRef
        String attClassName = xmap.getAttributeClassificationName();
        if (xmap.isSwaRef()) {
            attClassName = DATAHANDLER_CLASSNAME;
        }
        
        return processXMLMapping(
                (XMLField)xmap.getField(), 
                xmap.getAttributeName(), 
                xmap.getXPath(), 
                attClassName, 
                xmap.getNullPolicy(), 
                null,
                xmap.shouldInlineBinaryData(),
                xmap.isSwaRef(),
                xmap.getMimeType());
    }
 

    /**
     * Process a given XMLCompositeDirectCollectionMapping and return an XmlAttribute.
     * 
     */
    protected static XmlAttribute processXMLCompositeDirectCollectionMappingAttribute(XMLCompositeDirectCollectionMapping xmap) {
        return processXMLMapping(
                (XMLField)xmap.getField(), 
                xmap.getAttributeName(), 
                xmap.getXPath(), 
                null, 
                xmap.getNullPolicy(), 
                xmap.getContainerPolicy().getContainerClassName(),
                false,
                false,
                null);
    }
    
    /**
     * Process a given XMLDirectMapping and return an XmlAttribute.
     * 
     */
    protected static XmlAttribute processXMLDirectMappingAttribute(XMLDirectMapping xmap) {
        return processXMLMapping(
                (XMLField)xmap.getField(), 
                xmap.getAttributeName(), 
                xmap.getXPath(), 
                xmap.getAttributeClassificationName(), 
                xmap.getNullPolicy(), 
                null,
                false,
                false,
                null);
    }    

    /**
     * Process a given XMLMapping and return an XmlElement.
     * 
     */
    protected static XmlElement processXMLMapping(XMLField xfld, String attName, String xpath, String attClassification, 
            AbstractNullPolicy nullPolicy, boolean isCDATA, String containerName, boolean inlineBinary, boolean isSWARef, String mimeType) {

        XmlElement xElt = new XmlElement();
        xElt.setJavaAttribute(attName);
        xElt.setXmlPath(xpath);
        if (xfld.isRequired()) {
            xElt.setRequired(true);
        }
        if (isCDATA) {
            xElt.setCdata(true);
        }
        if (inlineBinary) {
            xElt.setXmlInlineBinaryData(true);
        }
        if (isSWARef) {
            xElt.setXmlAttachmentRef(true);
        }
        if (attClassification != null) {
            xElt.setType(attClassification);
        }
        if (containerName != null) {
            xElt.setContainerType(containerName);
        }
        if (mimeType != null) {
            xElt.setXmlMimeType(mimeType);
        }
        QName schemaType = xfld.getSchemaType();
        if (schemaType != null) {
            XmlSchemaType xSchemaType = new XmlSchemaType();
            xSchemaType.setName(schemaType.getLocalPart());
            xElt.setXmlSchemaType(xSchemaType);
        }
        if (!isDefaultNullPolicy(nullPolicy)) {
            XmlAbstractNullPolicy xmlNullPolicy;
            
            if (nullPolicy instanceof NullPolicy) {
                xmlNullPolicy = new XmlNullPolicy();
                ((XmlNullPolicy) xmlNullPolicy).setIsSetPerformedForAbsentNode(nullPolicy.getIsSetPerformedForAbsentNode());
            } else {
                xmlNullPolicy = new XmlIsSetNullPolicy();
            }
            xmlNullPolicy.setEmptyNodeRepresentsNull(nullPolicy.isNullRepresentedByEmptyNode());
            xmlNullPolicy.setXsiNilRepresentsNull(nullPolicy.isNullRepresentedByXsiNil());
            xmlNullPolicy.setNullRepresentationForXml(XmlMarshalNullRepresentation.fromValue(nullPolicy.getMarshalNullRepresentation().toString()));

            xElt.setXmlAbstractNullPolicy(new JAXBElement<XmlAbstractNullPolicy>(new QName("http://www.eclipse.org/eclipselink/xsds/persistence/oxm", "xml-null-policy"), XmlAbstractNullPolicy.class, xmlNullPolicy));
        }
        return xElt;
    }

    /**
     * Process a given XMLDirectMapping and return an XmlElement.
     * 
     */
    protected static XmlElement processXMLDirectMapping(XMLDirectMapping xmap) {
        return processXMLMapping(
                (XMLField)xmap.getField(), 
                xmap.getAttributeName(), 
                xmap.getXPath(), 
                xmap.getAttributeClassificationName(), 
                xmap.getNullPolicy(), 
                xmap.isCDATA(),
                null,
                false,
                false,
                null);
    }

    /**
     * Process a given XMLBinaryDataMapping and return an XmlElement.
     * 
     */
    protected static XmlElement processXMLBinaryDataMapping(XMLBinaryDataMapping xmap) {
        // JAXB expects a DataHandler in the object model for SwaRef
        String attClassName = xmap.getAttributeClassificationName();
        if (xmap.isSwaRef()) {
            attClassName = DATAHANDLER_CLASSNAME;
        }
        
        return processXMLMapping(
                (XMLField)xmap.getField(), 
                xmap.getAttributeName(), 
                xmap.getXPath(), 
                attClassName, 
                xmap.getNullPolicy(), 
                xmap.isCDATA(),
                null,
                xmap.shouldInlineBinaryData(),
                xmap.isSwaRef(),
                xmap.getMimeType());
    }

    /**
     * Process a given XMLCompositeDirectCollectionMapping and return an XmlElement.
     * 
     */
    protected static XmlElement processXMLCompositeDirectCollectionMapping(XMLCompositeDirectCollectionMapping xmap) {
        return processXMLMapping(
                (XMLField)xmap.getField(), 
                xmap.getAttributeName(), 
                xmap.getXPath(), 
                null, 
                xmap.getNullPolicy(), 
                xmap.isCDATA(),
                xmap.getContainerPolicy().getContainerClassName(),
                false,
                false,
                null);
    }

    /**
     * Process a given XMLCompositeObjectMapping and return an XmlElement.
     * 
     */
    protected static XmlElement processXMLCompositeObjectMapping(XMLCompositeObjectMapping xmap) {
        return processXMLMapping(
                (XMLField)xmap.getField(), 
                xmap.getAttributeName(), 
                xmap.getXPath(), 
                xmap.getReferenceClassName(), 
                xmap.getNullPolicy(), 
                false,
                null,
                false,
                false,
                null);
    }

    /**
     * Process a given XMLCompositeCollectionMapping and return an XmlElement
     * 
     */
    protected static XmlElement processXMLCompositeCollectionMapping(XMLCompositeCollectionMapping xmap) {
        return processXMLMapping(
                (XMLField)xmap.getField(), 
                xmap.getAttributeName(), 
                xmap.getXPath(), 
                xmap.getReferenceClassName(), 
                xmap.getNullPolicy(), 
                false,
                xmap.getContainerPolicy().getContainerClassName(),
                false,
                false,
                null);
    }

    /**
     * Convenience methods that returns the package name for a given fully 
     * qualified Java class name.
     * 
     */
    protected static String getPackageName(String javaClassName) {
        // handle 'default' package
        if (javaClassName.lastIndexOf(DOT) == -1) {
            return EMPTY_STRING;
        }
        return javaClassName.substring(0, javaClassName.lastIndexOf(DOT));
    }
    
    /**
     * Convenience methods that returns the class name w/o package 
     * for a given fully qualified Java class name.
     * 
     */
    protected static String getClassName(String javaClassName) {
        // handle 'default' package
        if (javaClassName.lastIndexOf(DOT) == -1) {
            return javaClassName;
        }
        return javaClassName.substring(javaClassName.lastIndexOf(DOT)+1, javaClassName.length());
    }

    /**
     * Indicates is a given AbstractNullPolicy is the default.  This is useful
     * if it is not desirable to write out the default policy in the oxm
     * metadata file.
     * 
     * The default policy is NullPolicy, with the following set:
     * <ul>
     * <li>isNullRepresentedByXsiNil = false
     * <li>isNullRepresentedByEmptyNode = true
     * <li>isSetPerformedForAbsentNode = true
     * <li>marshalNullRepresentation = XMLNullRepresentationType.ABSENT_NODE
     * </ul>
     */
    protected static boolean isDefaultNullPolicy(AbstractNullPolicy nullPolicy) {
        // default policy is NullPolicy
        if (nullPolicy instanceof IsSetNullPolicy) {
            return false;
        }
        boolean xsiNil = nullPolicy.isNullRepresentedByXsiNil();
        boolean emptyNode = nullPolicy.isNullRepresentedByEmptyNode();
        boolean setForAbsent = nullPolicy.getIsSetPerformedForAbsentNode();
        XMLNullRepresentationType marshalNull = nullPolicy.getMarshalNullRepresentation();

        return (!xsiNil && emptyNode && setForAbsent && marshalNull == XMLNullRepresentationType.ABSENT_NODE);
    }
}
