/*
 * Copyright (c) 1998, 2019 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.internal.helper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;

import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.expressions.ForUpdateClause;
import org.eclipse.persistence.internal.expressions.SQLSelectStatement;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.platform.database.OraclePlatform;
import org.eclipse.persistence.queries.Call;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.WriteObjectQuery;

/**
 * INTERNAL:
 * <p><b>Purpose</b>:LOBValueWriter is used to write a large size of object into an Oracle
 * CLOB/BLOB column through Oracle LOB Locator. It's a work-around object for the well-known 4k write
 * limits on an Oracle thin driver.
 *
 * <p><b>Responsibilities</b>:<ul>
 * <li> Build the Oracle empty lob method call string for the insert call.
 * <li> Build the minimal SELECT call to retrieve the locator.
 * <li> Write the lob value through the locator.
 * <li> Resolve the multiple table INSERT/SELECT orders.
 * <li> Resolve the nested unit of work commit issue.
 * </ul>
 *
 * @author King Wang
 * @since TopLink/Java 5.0. July 2002.
 */
public class LOBValueWriter {
    //DatabaseCalls still to be processed
    private Collection calls = null;
    private Accessor accessor;
    private boolean isNativeConnectionRequired;

    /**
     * This is the default constructor for the class.
     *
     * Bug 2804663 - Each DatabaseAccessor will now hold on to its own instance
     * of this class, hence a singleton pattern is not applicable.
     */
    public LOBValueWriter(Accessor accessor) {
        this.accessor = accessor;
        DatabasePlatform platform = ((DatabaseAccessor)accessor).getPlatform();
        this.isNativeConnectionRequired = platform.isOracle() && ((OraclePlatform)platform).isNativeConnectionRequiredForLobLocator();
    }

    protected void buildAndExecuteCall(DatabaseCall dbCall, AbstractSession session) {
        DatabaseQuery query = dbCall.getQuery();
        if (!query.isWriteObjectQuery()) {
            //if not writequery, should not go through the locator writing..
            return;
        }
        WriteObjectQuery writeQuery = (WriteObjectQuery)query;
        writeQuery.setAccessor(accessor);
        //build a select statement form the query
        SQLSelectStatement selectStatement = buildSelectStatementForLocator(writeQuery, dbCall, session);

        //then build a call from the statement
        DatabaseCall call = buildCallFromSelectStatementForLocator(selectStatement, writeQuery, dbCall, session);

        accessor.executeCall(call, call.getQuery().getTranslationRow(), session);
    }

    /**
    * Fetch the locator(s) from the result set and write LOB value to the table
    */
    public void fetchLocatorAndWriteValue(DatabaseCall dbCall, Object resultSet) throws SQLException {
        Enumeration enumFields = dbCall.getContexts().getFields().elements();
        Enumeration enumValues = dbCall.getContexts().getValues().elements();
        AbstractSession executionSession = dbCall.getQuery().getSession().getExecutionSession(dbCall.getQuery());
        while (enumFields.hasMoreElements()) {
            DatabaseField field = (DatabaseField)enumFields.nextElement();
            Object value = enumValues.nextElement();

            //write the value through the locator
            executionSession.getPlatform().writeLOB(field, value, (ResultSet)resultSet, executionSession);
        }
    }

    /**
    * Build the select statement for selecting the locator
    */
    private SQLSelectStatement buildSelectStatementForLocator(WriteObjectQuery writeQuery, DatabaseCall call, AbstractSession session) {
        SQLSelectStatement selectStatement = new SQLSelectStatement();
        Vector tables = writeQuery.getDescriptor().getTables();
        selectStatement.setTables(tables);
        //rather than get ALL fields from the descriptor, only use the LOB-related fields to build the minimal SELECT statement.
        selectStatement.setFields(call.getContexts().getFields());
        //the where clause setting here is sufficient if the object does not map to multiple tables.
        selectStatement.setWhereClause(writeQuery.getDescriptor().getObjectBuilder().buildPrimaryKeyExpressionFromObject(writeQuery.getObject(), session));
        //need pessimistic locking for the locator select
        selectStatement.setLockingClause(ForUpdateClause.newInstance(ObjectBuildingQuery.LOCK));

        if (tables.size() > 1) {
            //the primary key expression from the primary table
            Expression expression = selectStatement.getWhereClause();

            //additional join from the non-primary tables
            Expression additionalJoin = writeQuery.getDescriptor().getQueryManager().getAdditionalJoinExpression();
            if (additionalJoin != null) {
                expression = expression.and(additionalJoin);
            }

            //where clause now contains extra joins across all tables
            selectStatement.setWhereClause(expression);
        }

        //normalize the statement at the end, such as assign alias to all tables, and build sorting statement
        selectStatement.normalize(session, writeQuery.getDescriptor());
        return selectStatement;
    }

    /**
    * Build the sql call from the select statement for selecting the locator
    */
    private DatabaseCall buildCallFromSelectStatementForLocator(SQLSelectStatement selectStatement, WriteObjectQuery writeQuery, DatabaseCall dbCall, AbstractSession session) {
        DatabaseCall call = selectStatement.buildCall(session);
        // Locator LOB must not be wrapped (WLS wraps LOBs).
        call.setIsNativeConnectionRequired(this.isNativeConnectionRequired);

        //the LOB context must be passed into the new call object
        call.setContexts(dbCall.getContexts());
        //need to explicitly define one row return, otherwise, EL assumes multiple rows return and confuses the accessor
        call.returnOneRow();
        //the query object has to be set in order to access to the platform and login objects
        call.setQuery(writeQuery);
        // prepare it
        call.prepare(session);
        //finally do the translation
        call.translate(writeQuery.getTranslationRow(), writeQuery.getModifyRow(), session);
        return call;
    }

    // Building of SELECT statements is no longer done in DatabaseAccessor.basicExecuteCall
    // for updates because DatabaseCall.isUpdateCall() can't recognize update in case
    // StoredProcedureCall is used. Therefore in all cases: insert(single or multiple tables)
    // and update the original (insert and update) calls are saved
    // and both building and executing of SELECT statements postponed until
    // buildAndExecuteSelectCalls method is called.

    /**
    * Add original (insert or update) call to the collection
    */
    public void addCall(Call call) {
        if (calls == null) {
            //use lazy initialization
            calls = new ArrayList(2);
        }
        calls.add(call);
    }

    // Bug 3110860: RETURNINGPOLICY-OBTAINED PK CAUSES LOB TO BE INSERTED INCORRECTLY
    // The deferred locator SELECT calls should be generated and executed after ReturningPolicy
    // merges PK obtained from the db into the object held by the query.
    // That's why original (insert or update) calls are saved,
    // and both building and executing of SELECT statements postponed until
    // this method is called.

    /**
    * Build and execute the deferred select calls.
    */
    public void buildAndExecuteSelectCalls(AbstractSession session) {
        if ((calls == null) || calls.isEmpty()) {
            //no deferred select calls (it means no locator is required)
            return;
        }

        //all INSERTs have been executed, time to execute the SELECTs
        try {
            for (Iterator callIt = calls.iterator(); callIt.hasNext();) {
                DatabaseCall dbCall = (DatabaseCall)callIt.next();
                buildAndExecuteCall(dbCall, session);
            }
        } finally {
            //after executing all select calls, need to empty the collection.
            //this is necessary in the nested unit of work cases.
            calls.clear();
        }
    }
}
