/*
 * Copyright (c) 1998, 2021 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.oxm.mappings;

import jakarta.activation.DataHandler;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.oxm.XMLBinaryDataHelper;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataMapping;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.record.DOMRecord;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.sessions.Session;

/**
 * <p><b>Purpose:</b>Provide a mapping for binary data that can be treated as either inline or as
 * an attachment.
 * <p><b>Responsibilities:</b><ul>
 * <li>Handle converting binary types (byte[], Image etc) to base64</li>
 * <li>Make callbacks to AttachmentMarshaller/AttachmentUnmarshaller</li>
 * <li>Write out approriate attachment information (xop:include) </li>
 * </ul>
 *  <p>XMLBinaryDataMapping represents a mapping of binary data in the object model
 *  to XML. This can either be written directly as inline binary data (base64) or
 *  passed through as an MTOM or SWAREF attachment.
 *  <p>The following typed are allowable to be mapped using an XMLBinaryDataMapping:<ul>
 *  <li>java.awt.Image</li>
 *  <li>byte[]</li>
 *  <li>jakarta.activation.DataHandler</li>
 *  <li>javax.xml.transform.Source</li>
 *  <li>javax.mail.internet.MimeMultipart</li>
 *  </ul>
 *  <p><b>Setting the XPath</b>: TopLink XML mappings make use of XPath statements to find the relevant
 * data in an XML document.  The XPath statement is relative to the context node specified in the descriptor.
 * The XPath may contain path and positional information;  the last node in the XPath forms the local
 * node for the binary mapping. The XPath is specified on the mapping using the <code>setXPath</code>
 * method.
 *
 * <p><b>Inline Binary Data</b>: Set this flag if you want to always inline binary data for this mapping.
 * This will disable consideration for attachment handling for this mapping.
 *
 * <p><b>SwaRef</b>: Set this flag in order to specify that the target node of this mapping is of type
 * xs:swaref
 *
 *  @see org.eclipse.persistence.oxm.attachment.XMLAttachmentMarshaller
 *  @see org.eclipse.persistence.oxm.attachment.XMLAttachmentUnmarshaller
 *  @see org.eclipse.persistence.oxm.mappings.MimeTypePolicy
 *  @since   TopLink 11.1.1.0.0g
 */
public class XMLBinaryDataMapping extends XMLDirectMapping implements BinaryDataMapping<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, MimeTypePolicy, Session, XMLUnmarshaller, XMLRecord> {
    private boolean shouldInlineBinaryData;
    private MimeTypePolicy mimeTypePolicy;
    private boolean isSwaRef;
    private static final String include = ":Include/@href";

    public XMLBinaryDataMapping() {
    }

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

    @Override
    public void setShouldInlineBinaryData(boolean b) {
        shouldInlineBinaryData = b;
    }

    /**
     * INTERNAL
     */
    @Override
    public String getMimeType(Object anObject) {
        if (mimeTypePolicy == null) {
            return null;
        } else {
            return mimeTypePolicy.getMimeType(anObject);
        }
    }

    /**
     * INTERNAL
     */
    @Override
    public String getMimeType() {
        if(mimeTypePolicy == null) {
            return null;
        }
        return mimeTypePolicy.getMimeType(null);
    }

    public MimeTypePolicy getMimeTypePolicy() {
        return mimeTypePolicy;
    }

    /**
     * Allow implementer to set the MimeTypePolicy class FixedMimeTypePolicy or AttributeMimeTypePolicy (dynamic)
     * @param aPolicy MimeTypePolicy
     */
    @Override
    public void setMimeTypePolicy(MimeTypePolicy aPolicy) {
        mimeTypePolicy = aPolicy;
    }

    /**
     * Force mapping to set default FixedMimeTypePolicy using the MimeType string as argument
     */
    @Override
    public void setMimeType(String mimeTypeString) {
        // use the following to set dynamically - mapping.setMimeTypePolicy(new FixedMimeTypePolicy(property.getMimeType()));
        mimeTypePolicy = new FixedMimeTypePolicy(mimeTypeString);
    }

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

    @Override
    public void setSwaRef(boolean swaRef) {
        isSwaRef = swaRef;
    }

    /**
     * Set the Mapping field name attribute to the given XPath String
     * @param xpathString String
     */
    @Override
    public void setXPath(String xpathString) {
        setField(new XMLField(xpathString));
    }

    @Override
    public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session, WriteType writeType) {
        Object attributeValue = getAttributeValueFromObject(object);
        if (attributeValue == null) {
            XMLField field = (XMLField) getField();

            if(getNullPolicy() != null && !field.getXPathFragment().isSelfFragment()) {
               getNullPolicy().directMarshal((Field) this.getField(), (XMLRecord) row, object);
            }
            return;
        }
        writeSingleValue(attributeValue, object, (XMLRecord) row, session);
    }

    @Override
    public void writeSingleValue(Object attributeValue, Object parent, XMLRecord record, AbstractSession session) {
        XMLMarshaller marshaller = record.getMarshaller();
        attributeValue = convertObjectValueToDataValue(attributeValue, session, record.getMarshaller());
        XMLField field = (XMLField) getField();
        if (field.getLastXPathFragment().isAttribute()) {
            if (isSwaRef() && (marshaller.getAttachmentMarshaller() != null)) {
                //should be a DataHandler here
                try {
                    String value = null;
                    if (getAttributeClassification() == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) {
                        value = marshaller.getAttachmentMarshaller().addSwaRefAttachment((DataHandler) attributeValue);
                    } else {
                        XMLBinaryDataHelper.EncodedData data = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(//
                                attributeValue, marshaller, getMimeType(parent));
                        byte[] bytes = data.getData();
                        value = marshaller.getAttachmentMarshaller().addSwaRefAttachment(bytes, 0, bytes.length);

                    }
                    record.put(field, value);
                } catch (ClassCastException cce) {
                    throw XMLMarshalException.invalidSwaRefAttribute(getAttributeClassification().getName());
                }
            } else {
                //inline case
                XMLBinaryDataHelper.EncodedData data = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(attributeValue, record.getMarshaller(), getMimeType(parent));
                String base64Value = ((XMLConversionManager) session.getDatasourcePlatform().getConversionManager()).buildBase64StringFromBytes(data.getData());
                record.put(field, base64Value);
            }
            return;
        }
        if (record.isXOPPackage() && !isSwaRef() && !shouldInlineBinaryData()) {
            //write as attachment
            String c_id = XMLConstants.EMPTY_STRING;
            byte[] bytes = null;
            String elementName = field.getLastXPathFragment().getLocalName();
            String namespaceUri = field.getLastXPathFragment().getNamespaceURI();
            if(field.getLastXPathFragment().isSelfFragment()) {
                //If it's a self mapping, get the element from the DOM record
                DOMRecord domRecord = (DOMRecord)record;
                if(domRecord.getDOM().getNodeType() == Node.ELEMENT_NODE) {
                    elementName = domRecord.getDOM().getLocalName();
                    namespaceUri = domRecord.getDOM().getNamespaceURI();
                }
            }
            if ((getAttributeClassification() == ClassConstants.ABYTE) || (getAttributeClassification() == ClassConstants.APBYTE)) {
                if (getAttributeClassification() == ClassConstants.ABYTE) {
                    attributeValue = session.getDatasourcePlatform().getConversionManager().convertObject(attributeValue, ClassConstants.APBYTE);
                }
                bytes = (byte[])attributeValue;
                c_id = marshaller.getAttachmentMarshaller().addMtomAttachment(//
                        bytes, 0,//
                        bytes.length,//
                        this.getMimeType(parent),//
                        elementName,//
                        namespaceUri);//
            } else if (getAttributeClassification() == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) {
                c_id = marshaller.getAttachmentMarshaller().addMtomAttachment(//
                        (DataHandler) attributeValue, elementName, namespaceUri);
                if(c_id == null) {
                    //get the bytes so we can write it out inline
                    XMLBinaryDataHelper.EncodedData data = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(//
                            attributeValue, marshaller, getMimeType(parent));
                    bytes = data.getData();
                }
            } else {
                XMLBinaryDataHelper.EncodedData data = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(//
                        attributeValue, marshaller, getMimeType(parent));
                bytes = data.getData();
                c_id = marshaller.getAttachmentMarshaller().addMtomAttachment(bytes, 0,//
                        bytes.length,//
                        data.getMimeType(),//
                        elementName,//
                        namespaceUri);
            }
            if(c_id == null) {
                XMLField textField = null;
                if(field.isSelfField()){
                    textField = new XMLField(XMLConstants.TEXT);
                }else{
                    textField = new XMLField(field.getXPath() + '/' + XMLConstants.TEXT);
                }
                textField.setNamespaceResolver(field.getNamespaceResolver());
                textField.setSchemaType(field.getSchemaType());
                record.put(textField, bytes);
                //write out bytes inline
            } else {
                String xpath = this.getXPath();
                String prefix = null;
                boolean prefixAlreadyDefined = false;
                //  If the field's resolver is non-null and has an entry for XOP,
                //  use it - otherwise, create a new resolver, set the XOP entry,
                // on it, and use it instead.
                // We do this to avoid setting the XOP namespace declaration on
                // a given field or descriptor's resolver, as it is only required
                // on the current element
                NamespaceResolver resolver = field.getNamespaceResolver();
                if (resolver != null) {
                    prefix = resolver.resolveNamespaceURI(XMLConstants.XOP_URL);
                }
                if (prefix == null) {
                    prefix = XMLConstants.XOP_PREFIX;
                    resolver = new NamespaceResolver();
                    resolver.put(prefix, XMLConstants.XOP_URL);
                } else {
                    prefixAlreadyDefined = true;
                }


                String incxpath = null;
                if(field.isSelfField()){
                    incxpath = prefix + ":Include";
                    xpath = (prefix + include);
                }else{
                    incxpath = xpath + '/' + prefix + ":Include";
                    xpath += ('/' + prefix + include);
                }

                XMLField xpathField = new XMLField(xpath);
                xpathField.setNamespaceResolver(resolver);
                record.put(xpathField, c_id);

                // Need to call setAttributeNS on the record, unless the xop prefix
                // is defined on the descriptor's resolver already
                XMLField incField = new XMLField(incxpath);
                incField.setNamespaceResolver(resolver);
                Object obj = record.getIndicatingNoEntry(incField);
                if (!prefixAlreadyDefined && obj != null && obj instanceof DOMRecord) {
                    if (((DOMRecord) obj).getDOM().getNodeType() == Node.ELEMENT_NODE) {
                        ((Element) ((DOMRecord) obj).getDOM()).setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + XMLConstants.COLON + prefix, XMLConstants.XOP_URL);
                    }
                }
            }
        } else if (isSwaRef() && (marshaller.getAttachmentMarshaller() != null)) {
            //AttributeValue should be a data-handler
            try {
                String c_id = null;
                if (getAttributeClassification() == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) {
                    c_id = marshaller.getAttachmentMarshaller().addSwaRefAttachment((DataHandler) attributeValue);
                } else {
                    XMLBinaryDataHelper.EncodedData data = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(//
                            attributeValue, marshaller, getMimeType(parent));
                    byte[] bytes = data.getData();
                    c_id = marshaller.getAttachmentMarshaller().addSwaRefAttachment(bytes, 0, bytes.length);
                }
                XMLField textField = new XMLField(field.getXPath() + '/' + XMLConstants.TEXT);
                textField.setNamespaceResolver(field.getNamespaceResolver());
                textField.setSchemaType(field.getSchemaType());
                record.put(textField, c_id);
            } catch (Exception ex) {
            }
        } else {
            //inline
            XMLField textField = null;
            if(field.isSelfField()){
                textField = new XMLField(XMLConstants.TEXT);
            }else{
                textField = new XMLField(field.getXPath() + '/' + XMLConstants.TEXT);
            }
            textField.setNamespaceResolver(field.getNamespaceResolver());
            textField.setSchemaType(field.getSchemaType());
            if ((getAttributeClassification() == ClassConstants.ABYTE) || (getAttributeClassification() == ClassConstants.APBYTE)) {
                record.put(textField, attributeValue);
            } else {
                byte[] bytes = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(//
                        attributeValue, marshaller, getMimeType(parent)).getData();
                record.put(textField, bytes);
            }
        }
    }

    @Override
    public Object valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery query, CacheKey cacheKey, AbstractSession executionSession, boolean isTargetProtected, Boolean[] wasCacheUsed) {
        // PERF: Direct variable access.
        Object value = row.get(this.field);
        if (value == null) {
            return value;
        }
        Object fieldValue = null;
        XMLUnmarshaller unmarshaller = ((XMLRecord) row).getUnmarshaller();
        if (value instanceof String) {
            if (this.isSwaRef() && (unmarshaller.getAttachmentUnmarshaller() != null)) {
                if (getAttributeClassification() == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) {
                    fieldValue = unmarshaller.getAttachmentUnmarshaller().getAttachmentAsDataHandler((String) value);
                } else {
                    fieldValue = unmarshaller.getAttachmentUnmarshaller().getAttachmentAsByteArray((String) value);
                }
            } else if (!this.isSwaRef()) {
                //should be base64
                byte[] bytes = ((XMLConversionManager) executionSession.getDatasourcePlatform().getConversionManager()).convertSchemaBase64ToByteArray(value);
                fieldValue = bytes;
            }
        } else if(value instanceof byte[] || value instanceof Byte[]){
            fieldValue = value;
        } else {
            //this was an element, so do the XOP/SWAREF/Inline binary cases for an element
            XMLRecord record = (XMLRecord) value;

            if (getNullPolicy().valueIsNull((Element) record.getDOM())) {
                return null;
            }


            record.setSession(executionSession);

            if ((unmarshaller.getAttachmentUnmarshaller() != null) && unmarshaller.getAttachmentUnmarshaller().isXOPPackage() && !this.isSwaRef() && !this.shouldInlineBinaryData()) {
                //look for the include element:
                String xpath = XMLConstants.EMPTY_STRING;
                //  need a prefix for XOP
                String prefix = null;
                NamespaceResolver descriptorResolver = ((XMLDescriptor) getDescriptor()).getNamespaceResolver();
                // 20061023: handle NPE on null NSR
                if (descriptorResolver != null) {
                    prefix = descriptorResolver.resolveNamespaceURI(XMLConstants.XOP_URL);
                }
                if (prefix == null) {
                    prefix = XMLConstants.XOP_PREFIX;
                }
                NamespaceResolver tempResolver = new NamespaceResolver();
                tempResolver.put(prefix, XMLConstants.XOP_URL);
                xpath = prefix + include;
                XMLField field = new XMLField(xpath);
                field.setNamespaceResolver(tempResolver);
                String includeValue = (String) record.get(field);
                if (includeValue != null) {
                    if ((getAttributeClassification() == ClassConstants.ABYTE) || (getAttributeClassification() == ClassConstants.APBYTE)) {
                        fieldValue = unmarshaller.getAttachmentUnmarshaller().getAttachmentAsByteArray(includeValue);
                    } else {
                        fieldValue = unmarshaller.getAttachmentUnmarshaller().getAttachmentAsDataHandler(includeValue);
                    }
                } else {
                    //If we didn't find the Include element, check for inline
                    fieldValue = record.get(XMLConstants.TEXT);
                    //should be a base64 string
                    fieldValue = ((XMLConversionManager) executionSession.getDatasourcePlatform().getConversionManager()).convertSchemaBase64ToByteArray(fieldValue);
                }
            } else if ((unmarshaller.getAttachmentUnmarshaller() != null) && isSwaRef()) {
                String refValue = (String) record.get(XMLConstants.TEXT);
                if (refValue != null) {
                    fieldValue = unmarshaller.getAttachmentUnmarshaller().getAttachmentAsDataHandler(refValue);
                }
            } else {
                fieldValue = record.get(XMLConstants.TEXT);
                //should be a base64 string
                if (fieldValue != null) {
                    fieldValue = ((XMLConversionManager) executionSession.getDatasourcePlatform().getConversionManager()).convertSchemaBase64ToByteArray(fieldValue);
                } else {
                    fieldValue = new byte[0];
                }
            }
        }
        Object attributeValue = convertDataValueToObjectValue(fieldValue, executionSession, unmarshaller);
        attributeValue = XMLBinaryDataHelper.getXMLBinaryDataHelper().convertObject(attributeValue, getAttributeClassification(), executionSession, null);

        return attributeValue;
    }

    @Override
    public boolean isAbstractDirectMapping() {
        return false;
    }

    @Override
    public boolean isAbstractColumnMapping() {
        return false;
    }

}
