/*
 * 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 org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.sessions.AbstractSession;

/**
 * <p><b>Purpose</b>:
 * This should only be used by the descriptor, this should not be executed directly.
 * Used to determine if an object resides on the database.
 * DoesExistQuery is normally used to determine whether to make an update
 * or insert statement when writing an object.
 *
 * <p><b>Responsibilities</b>:
 * Verify the existence of an object. Used only by a write object query.
 *
 * @author Yvon Lavoie
 * @since TOPLink/Java 1.0
 */
public class DoesExistQuery extends DatabaseQuery {
    public static final int AssumeNonExistence = 1;
    public static final int AssumeExistence = 2;
    public static final int CheckCache = 3;
    public static final int CheckDatabase = 4;

    /** Query that is performing the does exist check. */
    protected Object primaryKey;
    protected Object object;

    /** Flag to determine existence check policy. */
    protected int existencePolicy;

    /**
     * Flag to determine cache invalidation policy support.  This overrides
     * the CheckCache existence setting if the object is invalid or if the
     * cache cannot be trusted because a flush or DML has occurred.
     * The default is true.
     */
    protected boolean checkDatabaseIfInvalid; //default to true, allows users to override

    /**
     * Flag to determine if the cache should be check first in addition to another option.
     * The default is true;
     */
    public boolean checkCacheFirst; //default to true

    /**
     * PUBLIC:
     * Initialize the state of the query .
     * By default the cache is checked, if non cache is used the descriptor should throw a exception and validate.
     */
    public DoesExistQuery() {
        this.existencePolicy = CheckCache;
        this.checkDatabaseIfInvalid = true;
        this.checkCacheFirst = true;
    }

    /**
     * PUBLIC:
     * Create a query to check if the object exists.
     */
    public DoesExistQuery(Object object) {
        this();
        this.object = object;
    }

    /**
     * PUBLIC:
     * Create a query to check if the object exists.
     */
    public DoesExistQuery(Call call) {
        this();
        setCall(call);
    }

    /**
     * PUBLIC:
     * Assume that if the objects primary key does not include null then it must exist.
     * This may be used if the user's system guarantees that an object with non-null key exists.
     */
    public void assumeExistenceForDoesExist() {
        setExistencePolicy(AssumeExistence);
    }

    /**
     * PUBLIC:
     * Assume that the object does not exist.
     * This may be used if the user's system guarantees objects must always be inserted.
     */
    public void assumeNonExistenceForDoesExist() {
        setExistencePolicy(AssumeNonExistence);
    }

    /**
     * PUBLIC:
     * Assume that if the objects primary key does not include null
     * and it is in the cache, then is must exist.
     * This should only be used if a full identity map is being used,
     * and a new object in the client cannot have been inserted by another client.
     */
    public void checkCacheForDoesExist() {
        setExistencePolicy(CheckCache);
    }

    /**
     * PUBLIC:
     * Perform does exist check on the database through selecting the primary key.
     */
    public void checkDatabaseForDoesExist() {
        setExistencePolicy(CheckDatabase);
    }

    /**
     * INTERNAL:
     * Check if existence can be determined without going to the database.
     * Note that custom query check is not require for does exist as the custom is always used.
     * Used by unit of work, and will return null if checkDatabaseIfInvalid is set and the cachekey is invalidated
     */
    public Object checkEarlyReturn(Object object, Object primaryKey, AbstractSession session, AbstractRecord translationRow) {
        // For bug 3136413/2610803 building the selection criteria from an EJBQL string or
        // an example object is done just in time.
        buildSelectionCriteria(session);
        // Return false on null since it can't exist.  Little more done in case PK not set in the query
        if  (object == null){
            return Boolean.FALSE;
        }
        ClassDescriptor descriptor = session.getDescriptor(object.getClass());
        if (primaryKey == null) {
            primaryKey = getPrimaryKey();
            if (primaryKey == null) {
                primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(object, session, true);
            }

        }
        if (primaryKey == null) {
            return Boolean.FALSE;
        }

        // Need to do the cache check first if flag set or if we should check the cache only for existence.
        if ((shouldCheckCacheForDoesExist() ||this.checkCacheFirst) && !descriptor.isDescriptorForInterface()) {

            // If this is a UOW and modification queries have been executed, the cache cannot be trusted.
            if (this.checkDatabaseIfInvalid && (session.isUnitOfWork() &&  ((UnitOfWorkImpl)session).shouldReadFromDB())) {
                return null;
            }

            CacheKey cacheKey;
            Class objectClass = object.getClass();
            AbstractSession tempSession = session;
            if (tempSession.isUnitOfWork()){
                cacheKey = tempSession.getIdentityMapAccessorInstance().getCacheKeyForObjectForLock(primaryKey, objectClass, descriptor);
                if (cacheKey != null) {
                    // If in the UOW cache it can't be invalid.
                    return Boolean.TRUE;
                }
                while (((UnitOfWorkImpl)tempSession).isNestedUnitOfWork() ){ //could be nested lets check all UOWs
                    tempSession = tempSession.getParent();
                    cacheKey = tempSession.getIdentityMapAccessorInstance().getCacheKeyForObjectForLock(primaryKey, objectClass, descriptor);
                    if (cacheKey != null) {
                        // If in the UOW cache it can't be invalid.
                        return Boolean.TRUE;
                    }
                }
                tempSession = tempSession.getParentIdentityMapSession(descriptor, false, true);
            }
            // Did not find it registered in UOW so check main cache and check for invalidation.
            cacheKey = tempSession.getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey,objectClass, descriptor, false);

            if ((cacheKey != null)) {
                // Assume that if there is a cachekey, object exists.
                if (this.checkDatabaseIfInvalid) {
                    checkDescriptor(object, session);
                    if (this.descriptor.getCacheInvalidationPolicy().isInvalidated(cacheKey, System.currentTimeMillis())) {
                        return null;
                    }
                }

                Object objectFromCache = cacheKey.getObject();
                if ((session.isUnitOfWork()) && ((UnitOfWorkImpl)session).wasDeleted(objectFromCache)) {
                    if (shouldCheckCacheForDoesExist()) {
                        return Boolean.FALSE;
                    }
                } else {
                    return Boolean.TRUE;
                }
            } else if (shouldCheckCacheForDoesExist()) {
                // We know its not in cache, and a checkcache policy so return false.
                return Boolean.FALSE;
            }
        }
        // Check if we have to assume that the object does not exist.
        if (shouldAssumeNonExistenceForDoesExist()) {
            return Boolean.FALSE;
        }

        // Check to see if we only need to check that the object contains a primary key.
        if (shouldAssumeExistenceForDoesExist()) {
            return Boolean.TRUE;
        }

        return null;
    }

    /**
     * INTERNAL:
     * Check if existence can be determined without going to the database.
     * Note that custom query check is not require for does exist as the custom is always used.
     */
    @Override
    public Object checkEarlyReturn(AbstractSession session, AbstractRecord translationRow) {
        return checkEarlyReturn(getObject(), getPrimaryKey(), session, translationRow);
    }

    /**
     * INTERNAL:
     * Return if the object exists on the database.
     * This must be a Boolean object to conform with returning an object.
     * If using optimistic locking, check that the value matches.
     * @exception  DatabaseException - an error has occurred on the database.
     */
    @Override
    public Object executeDatabaseQuery() throws DatabaseException {
        // Get the required fields for does exist check.
        DatabaseField field = getDoesExistField();

        // Get row from database
        AbstractRecord databaseRow = getQueryMechanism().selectRowForDoesExist(field);

        // Null means no row was returned.
        return databaseRow != null;
    }

    /**
     * INTERNAL:
     * Return the write lock field or the first primary key field if not using locking.
     */
    protected DatabaseField getDoesExistField() {
        return this.descriptor.getPrimaryKeyFields().get(0);
    }

    /**
     * INTERNAL:
     * Return the existence policy for this existence Query
     */
    public int getExistencePolicy() {
        return this.existencePolicy;
    }

    /**
     * PUBLIC:
     * Return the object.
     */
    public Object getObject() {
        return object;
    }

    /**
     * INTERNAL:
     * Return the primaryKey.
     */
    public Object getPrimaryKey() {
        return primaryKey;
    }

    /**
     * Return the domain class associated with this query.
     */
    @Override
    public Class getReferenceClass() {
        if (getObject() == null) {
            return null;
        }
        return getObject().getClass();
    }

    /**
     * INTERNAL:
     * Return the name of the reference class for this query
     * Note: Although the API is designed to avoid requirement of classes being on the classpath,
     * this is not a user defined query type, so it is ok to access the class.
     */
    @Override
    public String getReferenceClassName() {
        return getReferenceClass().getName();
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    @Override
    protected void prepare() throws QueryException {

        if (getObject() != null) {// Prepare can be called without the object set yet.
            checkDescriptor(getObject(), getSession());
            setObject(getDescriptor().getObjectBuilder().unwrapObject(getObject(), getSession()));
        }

        super.prepare();

        // It will only get to prepare if check database if required.
        getQueryMechanism().prepareDoesExist(getDoesExistField());
    }

    /**
     * INTERNAL:
     * Ensure that the descriptor has been set.
     */
    public void checkDescriptor(Object object, AbstractSession session) throws QueryException {
        if (this.descriptor == null) {
            if (object == null) {
                throw QueryException.objectToModifyNotSpecified(this);
            }

            //Bug#3947714  Pass the object instead of class in case object is proxy
            ClassDescriptor referenceDescriptor = session.getDescriptor(object);
            if (referenceDescriptor == null) {
                throw QueryException.descriptorIsMissing(object.getClass(), this);
            }
            setDescriptor(referenceDescriptor);
        }
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    @Override
    public void prepareForExecution() throws QueryException {
        super.prepareForExecution();

        if (getObject() == null) {
            throw QueryException.objectToModifyNotSpecified(this);
        }
        setObject(this.descriptor.getObjectBuilder().unwrapObject(getObject(), getSession()));

        if (this.descriptor == null) {
            setDescriptor(getSession().getDescriptor(getObject().getClass()));
        }

        if (getPrimaryKey() == null) {
            setPrimaryKey(this.descriptor.getObjectBuilder().extractPrimaryKeyFromObject(getObject(), getSession()));
        }

        if ((getTranslationRow() == null) || (getTranslationRow().isEmpty())) {
            setTranslationRow(this.descriptor.getObjectBuilder().buildRowForTranslation(getObject(), getSession()));
        }
    }

    /**
     * INTERNAL:
     * Set if the existence policy, this must be set to one of the constants.
     */
    public void setExistencePolicy(int existencePolicy) {
        this.existencePolicy = existencePolicy;
    }

    /**
     * PUBLIC:
     * Set the object.
     */
    public void setObject(Object object) {
        this.object = object;
    }

    /**
     * INTERNAL:
     * Set the primaryKey.
     */
    public void setPrimaryKey(Object primaryKey) {
        this.primaryKey = primaryKey;
    }

    /**
     * PUBLIC:
     * Returns true if the does exist check should be based only
     * on whether the primary key of the object is set
     */
    public boolean shouldAssumeExistenceForDoesExist() {
        return existencePolicy == AssumeExistence;
    }

    /**
     * PUBLIC:
     * Returns true if the does exist check should assume non existence.
     */
    public boolean shouldAssumeNonExistenceForDoesExist() {
        return existencePolicy == AssumeNonExistence;
    }

    /**
     * PUBLIC:
     * Returns true if the does exist check should be based only
     * on a cache check.  Default behavior.
     */
    public boolean shouldCheckCacheForDoesExist() {
        return existencePolicy == CheckCache;
    }

    /**
     * PUBLIC:
     * Returns true if the does exist check should query the database.
     */
    public boolean shouldCheckDatabaseForDoesExist() {
        return existencePolicy == CheckDatabase;
    }

    /**
     * INTERNAL:
     * Sets checkCacheFirst flag.  If true, existence check will first go to the
     * cache.  It will then check other options if it is not found in the cache
     */
    public void setCheckCacheFirst(boolean checkCacheFirst){
        this.checkCacheFirst = checkCacheFirst;
    }
    /**
     * INTERNAL:
     */
    public boolean getCheckCacheFirst(){
        return this.checkCacheFirst;
    }

    /**
     * INTERNAL:
     * Sets checkDatabaseIfInvalid flag.  If true, query will go to the
     * database when it finds the object in the cache and it is invalid.
     * This is only valid when it checks the cache, and is true by default
     */
    public void setCheckDatabaseIfInvalid(boolean checkCacheFirst){
        this.checkCacheFirst = checkCacheFirst;
    }
    /**
     * INTERNAL:
     */
    public boolean getCheckDatabaseIfInvalid(){
        return this.checkCacheFirst;
    }
}
