/*
 * 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:
//     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 = Integer.valueOf(1);
                    } else {
                        result = Integer.valueOf(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;
    }
}
