/*
 * 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.eis;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.*;
import java.io.*;
import java.lang.reflect.*;
import jakarta.resource.*;
import jakarta.resource.cci.*;
import org.w3c.dom.Element;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.eis.interactions.*;
import org.eclipse.persistence.internal.databaseaccess.DatasourceCall;
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
import org.eclipse.persistence.internal.expressions.SQLStatement;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetMethod;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;

/**
 * <p>An <code>EISPlatform</code> defines any EIS adapter specific behavior.
 * This may include:
 * <ul>
 * <li>Instantiation of the adapter InteractionSpec
 * <li>Conversion from an adapter custom Record
 * <li>Perform platform specific record access
 * <li>Provide XML DOM record conversion
 * <li>Provide sequence support
 * </ul>
 *
 * <p><code>EISPlatform</code> also supports behavior for specifying the record
 * types supported and automatic data-conversion to strings.
 *
 * <p>Although use of the generic <code>EISPlatform</code> may be sufficient,
 * some adapters may require that a specific platform be defined.
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public class EISPlatform extends DatasourcePlatform {
    protected boolean isIndexedRecordSupported;
    protected boolean isMappedRecordSupported;
    protected boolean isDOMRecordSupported;

    /** Can be used for adapters that only support String data/XML. */
    protected boolean shouldConvertDataToStrings;

    /** Allows for usage of transaction to be disabled if not supported. */
    protected boolean supportsLocalTransactions;

    /** Can be used if a commit is required after every interaction outside of a local transaction. */
    protected boolean requiresAutoCommit;

    /** Can be used to convert from an adapter specific record. */
    protected RecordConverter recordConverter;

    /** Used to reflectively provide XML record support as DOMRecord is not part of the JCA-CCI spec. */
    protected Method domMethod;

    /** For XML usage, an XMLConversionManager instance is required */
    protected XMLConversionManager xmlConversionManager;

    /**
     * Default constructor.
     */
    public EISPlatform() {
        super();
        setIsMappedRecordSupported(true);
        setIsIndexedRecordSupported(true);
        setIsDOMRecordSupported(false);
        setShouldConvertDataToStrings(false);
        setSupportsLocalTransactions(true);
        setRequiresAutoCommit(false);
    }

    /**
     * Return the record converter.
     */
    public RecordConverter getRecordConverter() {
        return recordConverter;
    }

    /**
     * Set the record converter.
     * Can be used to convert from an adapter specific record.
     */
    public void setRecordConverter(RecordConverter recordConverter) {
        this.recordConverter = recordConverter;
    }

    /**
     * Return if this platform requires auto commit of the local transaction
     * for interactions outside of an interaction.
     */
    public boolean requiresAutoCommit() {
        return requiresAutoCommit;
    }

    /**
     * Set if this platform requires auto commit of the local transaction
     * for interactions outside of an interaction.
     */
    public void setRequiresAutoCommit(boolean requiresAutoCommit) {
        this.requiresAutoCommit = requiresAutoCommit;
    }

    /**
     * Return if this platform supports local transactions.
     */
    public boolean supportsLocalTransactions() {
        return supportsLocalTransactions;
    }

    /**
     * Set if this platform supports local transactions.
     */
    public void setSupportsLocalTransactions(boolean supportsLocalTransactions) {
        this.supportsLocalTransactions = supportsLocalTransactions;
    }

    /**
     * Return if this platform supports JCA IndexedRecord.
     */
    public boolean isIndexedRecordSupported() {
        return isIndexedRecordSupported;
    }

    /**
     * Set if this platform supports JCA IndexedRecord.
     */
    public void setIsIndexedRecordSupported(boolean isIndexedRecordSupported) {
        this.isIndexedRecordSupported = isIndexedRecordSupported;
    }

    /**
     * Return if this platform supports JCA MappedRecord.
     */
    public boolean isMappedRecordSupported() {
        return isMappedRecordSupported;
    }

    /**
     * Set if this platform supports JCA MappedRecord.
     */
    public void setIsMappedRecordSupported(boolean isMappedRecordSupported) {
        this.isMappedRecordSupported = isMappedRecordSupported;
    }

    /**
     * Return if this platform supports XML/DOM Records.
     */
    public boolean isDOMRecordSupported() {
        return isDOMRecordSupported;
    }

    /**
     * Set if this platform supports XML/DOM Records.
     */
    public void setIsDOMRecordSupported(boolean isDOMRecordSupported) {
        this.isDOMRecordSupported = isDOMRecordSupported;
    }

    /**
     * Return if all data set into the adapter should be first converted to strings.
     */
    public boolean shouldConvertDataToStrings() {
        return shouldConvertDataToStrings;
    }

    /**
     * Set if all data set into the adapter should be first converted to strings.
     */
    public void setShouldConvertDataToStrings(boolean shouldConvertDataToStrings) {
        this.shouldConvertDataToStrings = shouldConvertDataToStrings;
    }

    /**
     * Allow the platform to build the interaction spec based on properties defined in the interaction.
     */
    public InteractionSpec buildInteractionSpec(EISInteraction interaction) {
        return interaction.getInteractionSpec();
    }

    /**
     * Allow the platform to create the appropriate type of record for the interaction.
     */
    public jakarta.resource.cci.Record createInputRecord(EISInteraction interaction, EISAccessor accessor) {
        jakarta.resource.cci.Record input = interaction.createInputRecord(accessor);
        if (getRecordConverter() != null) {
            input = getRecordConverter().converterToAdapterRecord(input);
        }
        return input;
    }

    /**
     * Allow the platform to create the appropriate type of record for the interaction.
     * If an output record is not required then null is returned.
     */
    public jakarta.resource.cci.Record createOutputRecord(EISInteraction interaction, AbstractRecord translationRow, EISAccessor accessor) {
        return null;
    }

    /**
     * INTERNAL:
     * Allow the platform to handle record to row conversion.
     */
    public AbstractRecord buildRow(jakarta.resource.cci.Record record, EISInteraction interaction, EISAccessor accessor) {
        jakarta.resource.cci.Record output = record;
        if (getRecordConverter() != null) {
            output = getRecordConverter().converterFromAdapterRecord(output);
        }
        return interaction.buildRow(output, accessor);
    }

    /**
     * Allow the platform to handle record to row conversion.
     */
    public Vector<AbstractRecord> buildRows(jakarta.resource.cci.Record record, EISInteraction interaction, EISAccessor accessor) {
        jakarta.resource.cci.Record output = record;
        if (getRecordConverter() != null) {
            output = getRecordConverter().converterFromAdapterRecord(output);
        }
        return interaction.buildRows(output, accessor);
    }

    /**
     * Allow the platform to handle the creation of the DOM record.
     * By default create a mapped record an assume it implements DOM as well.
     */
    public jakarta.resource.cci.Record createDOMRecord(String recordName, EISAccessor accessor) {
        try {
            return accessor.getRecordFactory().createMappedRecord(recordName);
        } catch (ResourceException exception) {
            throw EISException.resourceException(exception, accessor, null);
        }
    }

    /**
     * INTERNAL:
     * Allow the platform to handle the creation of the Record for the DOM record.
     * By default instantiate an EISDOMRecord which introspects the record for a getDOM method.
     */
    public AbstractRecord createDatabaseRowFromDOMRecord(jakarta.resource.cci.Record record, EISInteraction call, EISAccessor accessor) {
        return new EISDOMRecord(record);
    }

    /**
     * Retrieves the field value from the record.
     * This allows for the platform to perform any platform specific translation or conversion.
     */
    public Object getValueFromRecord(String key, MappedRecord record, EISAccessor accessor) {
        return record.get(key);
    }

    /**
     * Stores the XML DOM value into the record.
     * This must be implemented by the platform if it support XML/DOM records.
     */
    public void setDOMInRecord(Element dom, jakarta.resource.cci.Record record, EISInteraction call, EISAccessor accessor) {
        if (domMethod == null) {
            @SuppressWarnings({"unchecked", "rawtypes"})
            Class<?>[] argumentTypes = (Class<?>[]) new Class[1];
            argumentTypes[0] = Element.class;
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    domMethod = AccessController.doPrivileged(new PrivilegedGetMethod(record.getClass(), "setDom", argumentTypes, false));
                }else{
                    domMethod = PrivilegedAccessHelper.getMethod(record.getClass(), "setDom", argumentTypes, false);
                }
            } catch (Exception notFound) {
                try {
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                        domMethod = AccessController.doPrivileged(new PrivilegedGetMethod(record.getClass(), "setDOM", argumentTypes, false));
                    }else{
                        domMethod = PrivilegedAccessHelper.getMethod(record.getClass(), "setDOM", argumentTypes, false);
                    }
                } catch (Exception cantFind) {
                    throw new EISException(cantFind);
                }
            }
        }
        try {
            Object[] arguments = new Object[1];
            arguments[0] = dom;
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try{
                    AccessController.doPrivileged(new PrivilegedMethodInvoker<>(domMethod, record, arguments));
                }catch (PrivilegedActionException ex){
                    throw (Exception)ex.getCause();
                }
            }else{
                PrivilegedAccessHelper.invokeMethod(domMethod, record, arguments);
            }
        } catch (Exception error) {
            throw new EISException(error);
        }
    }

    /**
     * Stores the field value into the record.
     * This allows for the platform to perform any platform specific translation or conversion.
     */
    public void setValueInRecord(String key, Object value, MappedRecord record, EISAccessor accessor) {
        Object recordValue = value;
        if (shouldConvertDataToStrings() && !(value instanceof jakarta.resource.cci.Record) && !(value instanceof Collection)) {
            recordValue = getConversionManager().convertObject(value, ClassConstants.STRING);
        }
        record.put(key, recordValue);
    }

    /**
     * Add the parameter.
     * Convert the parameter to a string and write it.
     * Convert rows to XML strings.
     */
    @Override
    public void appendParameter(Call call, Writer writer, Object parameter) {
        if (parameter instanceof Vector) {
            Vector<?> records = (Vector<?>)parameter;

            // May be a collection of record.
            for (int index = 0; index < records.size(); index++) {
                appendParameter(call, writer, (records).elementAt(index));
            }
        } else if (parameter instanceof org.eclipse.persistence.oxm.record.DOMRecord) {
            String xml = ((org.eclipse.persistence.oxm.record.DOMRecord)parameter).transformToXML();

            // For some reason the transform always prints the XML header, so trim it off.
            int start = xml.indexOf('>');
            xml = xml.substring(start + 1);
            try {
                writer.write(xml);
            } catch (IOException exception) {
                throw ValidationException.fileError(exception);
            }
        } else {
            super.appendParameter(call, writer, parameter);
        }
    }

    /**
     * The platform holds its own instance of conversion manager to allow customization.
     */
    @Override
    public ConversionManager getConversionManager() {
        // For XML we need an XMLConversionManager instance
        if (isDOMRecordSupported()) {
            // Lazy init for serialization.
            if (xmlConversionManager == null) {
                // Clone the default to allow customers to easily override the conversion manager
                xmlConversionManager = (XMLConversionManager) XMLConversionManager.getDefaultXMLManager().clone();
                xmlConversionManager.setLoader(super.getConversionManager().getLoader());
            }
            return xmlConversionManager;
        }
        // For non-XML, return the ConversionManager instance from DatasourcePlatform
        return super.getConversionManager();
    }

    /**
     * INTERNAL:
     * Override this method to throw an exception by default.
     * Platforms that support dynamic querying can override this to generate an EISInteraction.
     */
    public DatasourceCall buildCallFromStatement(SQLStatement statement, DatabaseQuery query, AbstractSession session) {
        throw QueryException.noCallOrInteractionSpecified();
    }

    /**
     * INTERNAL:
     * Return the correct call type for the native query string.
     * This allows EIS platforms to use different types of native calls.
     */
    @Override
    public DatasourceCall buildNativeCall(String queryString) {
        return new QueryStringInteraction(queryString);
    }
}
