/*
 * 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 jakarta.resource.ResourceException;
import jakarta.resource.cci.Connection;
import jakarta.resource.cci.ConnectionMetaData;
import jakarta.resource.cci.Interaction;
import jakarta.resource.cci.InteractionSpec;
import jakarta.resource.cci.Record;
import jakarta.resource.cci.RecordFactory;

import org.eclipse.persistence.eis.interactions.EISInteraction;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.queries.Call;
import org.eclipse.persistence.sessions.SessionProfiler;

/**
 * <p><code>EISAccessor</code> is an implementation of the <code>Accessor</code>
 * interface.  It is responsible for:
 * <ul>
 * <li>Connecting via connection factory
 * <li>Local transactions
 * <li>Interaction execution
 * <li>Record translation
 * </ul>
 *
 * @see EISInteraction
 * @see EISLogin
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public class EISAccessor extends DatasourceAccessor {
    protected Connection cciConnection;
    protected RecordFactory recordFactory;

    /**
     *    Default Constructor.
     */
    public EISAccessor() {
        super();
    }

    /**
     *    Begin a local transaction.
     */
    @Override
    protected void basicBeginTransaction(AbstractSession session) throws EISException {
        try {
            if (getEISPlatform().supportsLocalTransactions()) {
                getCCIConnection().getLocalTransaction().begin();
            }
        } catch (ResourceException exception) {
            throw EISException.resourceException(exception, this, session);
        }
    }

    /**
     * Close the connection.
     */
    @Override
    protected void closeDatasourceConnection() {
        try {
            getCCIConnection().close();
        } catch (ResourceException exception) {
            throw EISException.resourceException(exception, this, null);
        }
    }

    /**
     * Commit the local transaction.
     */
    @Override
    protected void basicCommitTransaction(AbstractSession session) throws EISException {
        try {
            if (getEISPlatform().supportsLocalTransactions()) {
                getCCIConnection().getLocalTransaction().commit();
            }
        } catch (ResourceException exception) {
            throw EISException.resourceException(exception, this, session);
        }
    }

    /**
     * If logging is turned on and the CCI implementation supports meta data then display connection info.
     */
    @Override
    protected void buildConnectLog(AbstractSession session) {
        try {
            // Log connection information.
            if (session.shouldLog(SessionLog.CONFIG, SessionLog.CONNECTION)) {// Avoid printing if no logging required.
                ConnectionMetaData metaData = getCCIConnection().getMetaData();
                Object[] args = { metaData.getUserName(), metaData.getEISProductName(), metaData.getEISProductVersion(), Helper.cr(), "\t" };
                session.log(SessionLog.CONFIG, SessionLog.CONNECTION, "connected_user_database", args, this);
            }
        } catch (ResourceException exception) {
            // Some databases do not support metadata, ignore exception.
            session.warning("JDBC_driver_does_not_support_meta_data", SessionLog.CONNECTION);
        }
    }

    /**
     * Avoid super to have logging occur after possible manual auto-commit.
     */
    @Override
    public Object executeCall(Call call, AbstractRecord translationRow, AbstractSession session) throws DatabaseException {
        return basicExecuteCall(call, translationRow, session);
    }

    /**
     * Execute the interaction.
     * The execution can differ slightly depending on the type of interaction.
     * The call may be parameterized where the arguments are in the translation row.
     * The row will be empty if there are no parameters.
     * @return depending of the type either the row count, row or vector of rows.
     */
    @Override
    public Object basicExecuteCall(Call call, AbstractRecord translationRow, AbstractSession session) throws DatabaseException {
        // If the login is null, then this accessor has never been connected.
        if (getLogin() == null) {
            throw DatabaseException.databaseAccessorNotConnected();
        }

        Interaction interaction = null;
        Object result = null;
        EISInteraction eisCall = null;
        try {
            eisCall = (EISInteraction)call;
        } catch (ClassCastException e) {
            throw QueryException.invalidDatabaseCall(call);
        }

        // Record and check if auto-commit is required.
        // Some platforms may require this (AQ).
        boolean autoCommit = (!isInTransaction()) && getEISPlatform().requiresAutoCommit();
        if (autoCommit) {
            beginTransaction(session);
        }
        try {
            if (session.shouldLog(SessionLog.FINE, SessionLog.SQL)) {// pre-check to improve performance
                session.log(SessionLog.FINE, SessionLog.SQL, call.getLogString(this), null, this, false);
            }
            incrementCallCount(session);
            session.startOperationProfile(SessionProfiler.SqlPrepare, eisCall.getQuery(), SessionProfiler.ALL);
            Record input = null;
            Record output = null;
            try {
                interaction = getCCIConnection().createInteraction();
                input = getEISPlatform().createInputRecord(eisCall, this);
                output = getEISPlatform().createOutputRecord(eisCall, translationRow, this);
            } finally {
                session.endOperationProfile(SessionProfiler.SqlPrepare, eisCall.getQuery(), SessionProfiler.ALL);
            }
            session.startOperationProfile(SessionProfiler.StatementExecute, eisCall.getQuery(), SessionProfiler.ALL);
            try {
                boolean success = true;
                InteractionSpec interactionSpec = getEISPlatform().buildInteractionSpec(eisCall);
                if (output == null) {
                    output = interaction.execute(interactionSpec, input);
                } else {
                    success = interaction.execute(interactionSpec, input, output);
                }
                session.log(SessionLog.FINEST, SessionLog.QUERY, "adapter_result", output);
                if (eisCall.isNothingReturned()) {
                    if (success) {
                        result = 1;
                    } else {
                        result = 0;
                    }
                    // Fire the output parameter row to allow app to handle return value.
                    if (output != null) {
                        AbstractRecord outputRow = getEISPlatform().buildRow(output, eisCall, this);
                        if (outputRow != null) {
                            eisCall.getQuery().setProperty("output", outputRow);
                            if (session.hasEventManager()) {
                                session.getEventManager().outputParametersDetected(outputRow, eisCall);
                            }
                        }
                    }
                } else if (eisCall.isOneRowReturned()) {
                    result = getEISPlatform().buildRow(output, eisCall, this);
                } else {
                    result = getEISPlatform().buildRows(output, eisCall, this);
                }
                session.log(SessionLog.FINEST, SessionLog.QUERY, "data_access_result", output);
            } finally {
                session.endOperationProfile(SessionProfiler.StatementExecute, eisCall.getQuery(), SessionProfiler.ALL);
            }
        } catch (ResourceException exception) {
            // Ensure each resource is released, but still ensure that the real exception is thrown.
            if (interaction != null) {
                try {
                    interaction.close();
                } catch (Exception closeException) {
                    // Ignore error to avoid masking real exception.
                }
            }
            try {
                decrementCallCount();
            } catch (Exception closeException) {
                // Ignore error to avoid masking real exception.
            }
            try {
                if (autoCommit) {
                    commitTransaction(session);
                }
            } catch (Exception closeException) {
                // Ignore error to avoid masking real exception.
            }
            throw EISException.resourceException(exception, call, this, session);
        } catch (RuntimeException exception) {
            try {// Ensure that the statement is closed, but still ensure that the real exception is thrown.
                try {
                    if (interaction != null) {
                        interaction.close();
                    }
                } finally {
                    if (autoCommit) {
                        commitTransaction(session);
                    }
                }
            } catch (Exception closeException) {
            }
            throw exception;
        }

        boolean transactionCommitted = false;
        boolean countDecremented = false;
        // This is in separate try block to ensure that the real exception is not masked by the close exception.
        try {
            interaction.close();
            if (autoCommit) {
                commitTransaction(session);
            }
            transactionCommitted = true;
            decrementCallCount();
            countDecremented = true;
        } catch (ResourceException exception) {
            try {
                if (!transactionCommitted) {
                    if (autoCommit) {
                        commitTransaction(session);
                    }
                }
            } catch (Exception ignore) {
                // Ignore error to avoid masking real exception.
            }
            try {
                if (!countDecremented) {
                    decrementCallCount();
                }
            } catch (Exception ignore) {
                // Ignore error to avoid masking real exception.
            }
            throw EISException.resourceException(exception, this, session);
        }

        return result;
    }

    /**
     * Return the CCI connection to the EIS resource adapter.
     */
    public Connection getCCIConnection() {
        return (Connection)getDatasourceConnection();
    }

    /**
     * Return and cast the platform.
     */
    public EISPlatform getEISPlatform() {
        return (EISPlatform)getDatasourcePlatform();
    }

    /**
     * Return the RecordFactory.
     * The record factory is acquired from the ConnectionManager,
     * and used to create record to pass to interactions.
     */
    public RecordFactory getRecordFactory() {
        return recordFactory;
    }

    /**
     * Set the RecordFactory.
     * The record factory is acquired from the ConnectionManager,
     * and used to create record to pass to interactions.
     */
    public void setRecordFactory(RecordFactory recordFactory) {
        this.recordFactory = recordFactory;
    }

    /**
     * Rollback the local transaction on the datasource.
     */
    @Override
    public void basicRollbackTransaction(AbstractSession session) throws DatabaseException {
        try {
            if (getEISPlatform().supportsLocalTransactions()) {
                getCCIConnection().getLocalTransaction().rollback();
            }
        } catch (ResourceException exception) {
            throw EISException.resourceException(exception, this, session);
        }
    }

    /**
     * Return if the connection to the "data source" is connected.
     */
    @Override
    protected boolean isDatasourceConnected() {
        return isConnected;
    }
}
