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

import java.sql.*;
import java.util.*;

import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;

/**
 * <p><b>Purpose</b>:
 * Abstract class for CursoredStream and ScrolableCursor
 */
public abstract class Cursor implements Enumeration, Iterator, java.io.Serializable {

    /** The preparedStatement that holds the handle to the database that the results are read from. */
    protected transient Statement statement;

    /** The result set (cursor) that holds the handle to the database that the results are read from. */
    protected transient ResultSet resultSet;

    /** The session that executed the query for the stream. */
    protected transient AbstractSession session;

    /** The root session that executed the call for the query.  Knows the database platform. */
    protected transient AbstractSession executionSession;

    /** The fields expected in the result set. */
    protected transient Vector<DatabaseField> fields;

    /** Cached size of the stream. */
    protected int size = -1;

    /** Read query that initialize the stream. */
    public transient ReadQuery query;

    /** Query policy that initialize the stream. */
    public transient CursorPolicy policy;

    /** Internal collection of objects. */
    protected List<Object> objectCollection;

    /** Conforming instances found in memory when building the result. */
    protected Map<Object, Object> initiallyConformingIndex;

    /** SelectionCriteria {@literal &} translation row ready for incremental conforming. */
    protected Expression selectionCriteriaClone;
    protected AbstractRecord translationRow;
    /** Store the next row, for 1-m joining. */
    protected AbstractRecord nextRow;

    /** Current position in the objectCollection of the stream. */
    protected int position;

    /**
     * INTERNAL:
     * Default constructor.
     */
    protected Cursor() {
        super();
    }

    /**
     * INTERNAL:
     */
    protected Cursor(DatabaseCall call, CursorPolicy policy) {
        ReadQuery query = policy.getQuery();
        this.query = query;
        this.session = query.getSession();
        this.executionSession = session.getExecutionSession(query);
        this.statement = call.getStatement();
        this.fields = call.getFields();
        this.resultSet = call.getResult();
        this.policy = policy;
        this.objectCollection = new Vector();

        if (query.getSession().isUnitOfWork() && query.isObjectLevelReadQuery()) {
            // Call register on the cursor itself.  This will set up
            // incremental conforming by setting the
            // selection criteria clone and arguments, and building the
            // intially conforming index (scans the UOW cache).
            // The incremental registration/conforming is done
            // in retrieveNext/PreviousObject -> buildAndRegisterObject
            ((ObjectLevelReadQuery)query).registerResultInUnitOfWork(this, (UnitOfWorkImpl)this.session, query.getTranslationRow(), false);// object collection is empty, so setting irrelevant.
        }
    }

    /**
     * PUBLIC:
     * Closes the stream.
     * This should be performed whenever the user has finished with the stream.
     */
    public void close() throws DatabaseException {
        RuntimeException exception = null;
        try {
            if (isClosed()) {
                return;
            }
            try {
                getAccessor().closeCursor(this.resultSet, this.session);
                getAccessor().closeStatement(this.statement, this.session, null);
            } catch (RuntimeException caughtException) {
                exception = caughtException;
            } finally {
                //release the connection (back into the pool if Three tier)
                try {
                    //bug 4668234 -- used to only release connections on server sessions but should always release
                    this.session.releaseReadConnection(this.query.getAccessor());
                } catch (RuntimeException releaseException) {
                    if (exception == null) {
                        throw releaseException;
                    }

                    //else ignore
                }
                if (exception != null) {
                    throw exception;
                }
            }
            this.statement = null;
            this.resultSet = null;
            this.nextRow = null;
        } catch (SQLException sqlException) {
            throw DatabaseException.sqlException(sqlException, getAccessor(), getSession(), false);
        }
    }

    /**
     * Close in case not closed.
     */
    @Override
    protected void finalize() throws DatabaseException {
        close();
    }

    /**
     * INTERNAL:
     * Return the accessor associated with the cursor.
     */
    public DatabaseAccessor getAccessor() {
        // Assume we have a JDBC accessor
        try {
            return (DatabaseAccessor)this.query.getAccessor();
        } catch (ClassCastException e) {
            throw QueryException.invalidDatabaseAccessor(this.query.getAccessor());
        }
    }

    /**
     * INTERNAL:
     * Retrieve the size of the open cursor by executing a count on the same query as the cursor.
     */
    protected abstract int getCursorSize() throws DatabaseException, QueryException;

    /**
     * INTERNAL:
     * Return the fields for the stream.
     */
    public Vector<DatabaseField> getFields() {
        return fields;
    }

    /**
     * INTERNAL:
     * Conforming instances found in memory when building the result.
     * These objects are returned first by the cursor, and a fast lookup
     * is needed to make sure the same objects appearing in the cursor are
     * filtered out.
     */
    public Map<Object, Object> getInitiallyConformingIndex() {
        return initiallyConformingIndex;
    }

    /**
     * INTERNAL:
     * Return the internal object collection that stores the objects.
     */
    public List<Object> getObjectCollection() {
        return objectCollection;
    }

    /**
     * INTERNAL:
     * Return the number of items to be faulted in for the stream.
     */
    public int getPageSize() {
        return this.policy.getPageSize();
    }

    /**
     * INTERNAL:
     * Return the cursor policy.
     */
    public CursorPolicy getPolicy() {
        return policy;
    }

    /**
     * INTERNAL:
     * Return the position of the stream inside the object collection.
     */
    public abstract int getPosition();

    /**
     * INTERNAL:
     * Return the query associated with the stream.
     */
    public ReadQuery getQuery() {
        return this.query;
    }

    /**
     * INTERNAL:
     * Return the result set (cursor).
     */
    public ResultSet getResultSet() {
        return resultSet;
    }

    /**
     * INTERNAL:
     * The clone of the selection criteria is needed for in-memory conforming
     * each object read from the Cursor.
     */
    public Expression getSelectionCriteriaClone() {
        return selectionCriteriaClone;
    }

    /**
     * INTERNAL:
     * Return the handle to the session
     */
    public AbstractSession getSession() {
        return session;
    }

    /**
     * INTERNAL:
     * Returns the session the underlying call was executed on.  This root
     * session knows the database platform.
     */
    public AbstractSession getExecutionSession() {
        return executionSession;
    }

    /**
     * INTERNAL:
     * Return the Statement.
     */
    protected Statement getStatement() {
        return statement;
    }

    /**
     * INTERNAL:
     * Gets the translation row the query was executed with, used for incremental
     * conforming.
     */
    protected AbstractRecord getTranslationRow() {
        return translationRow;
    }

    /**
     * PUBLIC:
     * Return if the stream is closed.
     */
    public boolean isClosed() {
        return (this.resultSet == null);
    }

    /**
     * INTERNAL:
     * builds and registers an object from a row for cursors.
     * Behavior is different from the query version in that refreshing is not
     * supported.
     */
    protected Object buildAndRegisterObject(AbstractRecord row) {
        ReadQuery query = this.query;
        if (query.isObjectLevelReadQuery()) {
            ObjectLevelReadQuery objectQuery = (ObjectLevelReadQuery)query;
            if (objectQuery.hasBatchReadAttributes() && objectQuery.getBatchFetchPolicy().isIN()) {
                objectQuery.getBatchFetchPolicy().addDataResults(row);
            }
            if (this.session.isUnitOfWork() && (!query.isReportQuery()) && query.shouldMaintainCache()
                    && (objectQuery.shouldConformResultsInUnitOfWork() || objectQuery.getDescriptor().shouldAlwaysConformResultsInUnitOfWork())) {
                Object object = objectQuery.conformIndividualResult(
                        objectQuery.buildObject(row), (UnitOfWorkImpl)this.session, this.translationRow, this.selectionCriteriaClone, this.initiallyConformingIndex);
                // Notifies caller to continue until conforming instance found
                if (object == null) {
                    return InvalidObject.instance;
                }
                return object;
            }
        }
        return query.buildObject(row);
    }

    /**
     * INTERNAL:
     * Read the next row from the result set.
     */
    protected abstract Object retrieveNextObject() throws DatabaseException;

    /**
     * INTERNAL:
     * Set the fields for the stream.
     */
    protected void setFields(Vector<DatabaseField> fields) {
        this.fields = fields;
    }

    /**
     * INTERNAL:
     * Conforming instances found in memory when building the result.
     * These objects are returned first by the cursor, and a fast lookup
     * is needed to make sure the same objects appearing in the cursor are
     * filtered out.
     */
    public void setInitiallyConformingIndex(Map<Object, Object> index) {
        this.initiallyConformingIndex = index;
    }

    /**
     * INTERNAL:
     * Set the internal object collection
     */
    public void setObjectCollection(List<Object> collection) {
        objectCollection = collection;
    }

    /**
     * INTERNAL:
     * Set the cursor policy.
     */
    public void setPolicy(CursorPolicy policy) {
        this.policy = policy;
    }

    /**
     * INTERNAL:
     * Set the current position of the stream
     */
    protected void setPosition(int value) {
        position = value;
    }

    /**
     * INTERNAL:
     * Set the result set (cursor)
     */
    protected void setResultSet(ResultSet result) {
        resultSet = result;
    }

    /**
     * INTERNAL:
     * The clone of the selection criteria is needed for in-memory conforming
     * each object read from the Cursor.
     */
    public void setSelectionCriteriaClone(Expression expression) {
        this.selectionCriteriaClone = expression;
    }

    /**
     * INTERNAL:
     * Set the session handle
     */
    public void setSession(AbstractSession databaseSession) {
        session = databaseSession;
    }

    /**
     * INTERNAL:
     * Sets the session the underlying call was executed on.  This root
     * session knows the database platform.
     */
    protected void setExecutionSession(AbstractSession executionSession) {
        this.executionSession = executionSession;
    }

    /**
     * INTERNAL:
     * Set the cache size
     */
    public void setSize(int size) {
        this.size = size;
    }

    /**
     * INTERNAL:
     * Sets the translation row this query was executed with.  Used for
     * incremental conforming.
     */
    public void setTranslationRow(AbstractRecord row) {
        this.translationRow = row;
    }

    /**
     * PUBLIC:
     * Retrieve the size of the open cursor by executing a count on the same query as the cursor.
     *
     * If this cursor is conforming size() can only be an estimate.  cursor size
     * plus number of conforming instances found in memory will be returned.  The
     * union (actual result) may be smaller than this.
     */
    public int size() throws DatabaseException {
        if (this.size == -1) {
            this.size = getCursorSize();
            if (this.initiallyConformingIndex != null) {
                this.size += this.initiallyConformingIndex.size();
            }
        }
        return this.size;
    }

    /**
     * PUBLIC:
     * Remove is not support with cursors.
     */
    @Override
    public void remove() throws QueryException {
        QueryException.invalidOperation("remove");
    }

    /**
      * PUBLIC:
      * Release all objects read in so far.
      * This should be performed when reading in a large collection of
      * objects in order to preserve memory.
      */
    public void clear() {
        // If using 1-m joining need to release 1-m rows as well.
        if ((this.query != null) && this.query.isObjectLevelReadQuery() && ((ObjectLevelReadQuery)this.query).hasJoining()) {
            ((ObjectLevelReadQuery)this.query).getJoinedAttributeManager().clearDataResults();
        }
    }
}
