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

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

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

import jakarta.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.XmlBindings.JavaTypes;
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.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;

/**
 * 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 = "jakarta.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 {@code 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 {@code 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);
    }
}
