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

import java.util.Set;

import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.CommitManager;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.DatabaseMapping.WriteType;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.eclipse.persistence.descriptors.DescriptorEventManager;
import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.descriptors.FetchGroupManager;
import org.eclipse.persistence.tools.profiler.QueryMonitor;

/**
 * <p><b>Purpose</b>: Used for deleting objects.
 *
 * <p><b>Responsibilities</b>:
 * Extract primary key from object and delete it.
 *
 * @author Yvon Lavoie
 * @since TOPLink/Java 1.0
 */
public class DeleteObjectQuery extends ObjectLevelModifyQuery {
    /** PERF: By default only the translation row is used for deletes, the full row can be requested for custom deletes. */
    protected boolean isFullRowRequired = false;

    /** Indicates whether the query should use optimistic locking. */
    protected boolean usesOptimisticLocking;

    public DeleteObjectQuery() {
        super();
    }

    public DeleteObjectQuery(Object objectToDelete) {
        this();
        setObject(objectToDelete);
    }

    public DeleteObjectQuery(Call call) {
        this();
        setCall(call);
    }

    /**
     * ADVANCED:
     * Return if the full row is required by the delete query.
     * This can be set on custom delete queries if more than the objects primary key and version is required.
     */
    public boolean isFullRowRequired()
    {
        return isFullRowRequired;
    }

    /**
     * ADVANCED:
     * Set if the full row is required by the delete query.
     * This can be set on custom delete queries if more than the objects primary key and version is required.
     */
    public void setIsFullRowRequired(boolean isFullRowRequired)
    {
        this.isFullRowRequired = isFullRowRequired;
    }

    /**
     * INTERNAL:
     * Check to see if a custom query should be used for this query.
     * This is done before the query is copied and prepared/executed.
     * null means there is none.
     */
    @Override
    protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
        checkDescriptor(session);

        // check if user defined a custom query
        DescriptorQueryManager queryManager = this.descriptor.getQueryManager();
        if ((!isCallQuery())// this is not a hand-coded (custom SQL, SDK etc.) call
                 && (!isUserDefined())// and this is not a user-defined query (in the query manager)
                 && queryManager.hasDeleteQuery()) {// and there is a user-defined query (in the query manager)
            return queryManager.getDeleteQuery();
        }

        return null;
    }

    /**
     * INTERNAL:
     * Code was moved from UnitOfWork.internalExecuteQuery
     *
     * @param unitOfWork
     * @param translationRow
     * @return
     * @throws org.eclipse.persistence.exceptions.DatabaseException
     * @throws org.eclipse.persistence.exceptions.OptimisticLockException
     */
    @Override
    protected Object executeInUnitOfWorkObjectLevelModifyQuery(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
        Object result = unitOfWork.processDeleteObjectQuery(this);
        if (result != null) {
            // if the above method returned something then the unit of work
            //was not writing so the object has been stored to delete later
            //so return the object.  See the above method for the cases
            //where this object will be returned.
            return result;
        }
        return super.executeInUnitOfWorkObjectLevelModifyQuery(unitOfWork, translationRow);
    }

    /**
     * INTERNAL:
     * Returns the specific default redirector for this query type.  There are numerous default query redirectors.
     * See ClassDescriptor for their types.
     */
    @Override
    protected QueryRedirector getDefaultRedirector(){
        return descriptor.getDefaultDeleteObjectQueryRedirector();
    }

    /**
     * INTERNAL:
     * Perform the work to delete an object.
     * @return object - the object being deleted.
     */
    @Override
    public Object executeDatabaseQuery() throws DatabaseException, OptimisticLockException {
        AbstractSession session = getSession();
        CommitManager commitManager = session.getCommitManager();
        Object object = getObject();
        boolean isUnitOfWork = session.isUnitOfWork();
        try {
            // Check if the object has already been deleted, then no work is required.
            if (commitManager.isCommitCompletedInPostOrIgnore(object)) {
                return object;
            }
            ClassDescriptor descriptor = this.descriptor;
            // Check whether the object is already being deleted,
            // if it is, then there is a cycle, and the foreign keys must be nulled.
            if (commitManager.isCommitInPreModify(object)) {
                if (!commitManager.isShallowCommitted(object)) {
                    getQueryMechanism().updateForeignKeyFieldBeforeDelete();
                    if ((descriptor.getHistoryPolicy() != null) && descriptor.getHistoryPolicy().shouldHandleWrites()) {
                        descriptor.getHistoryPolicy().postUpdate(this);
                    }
                    commitManager.markShallowCommit(object);
                }
                return object;
            }
            commitManager.markPreModifyCommitInProgress(getObject());
            if (!isUnitOfWork) {
                session.beginTransaction();
            }
            DescriptorEventManager eventManager = descriptor.getEventManager();
            // PERF: Avoid events if no listeners.
            if (eventManager.hasAnyEventListeners()) {
                // Need to run pre-delete selector if available
                eventManager.executeEvent(new DescriptorEvent(DescriptorEventManager.PreDeleteEvent, this));
            }

            // Verify if deep shallow modify is turned on
            if (shouldCascadeParts()) {
                descriptor.getQueryManager().preDelete(this);
            }

            // Check for deletion dependencies.
            if (isUnitOfWork) {
                Set dependencies = ((UnitOfWorkImpl)session).getDeletionDependencies(object);
                if (dependencies != null) {
                    for (Object dependency : dependencies) {
                        if (!commitManager.isCommitCompletedInPostOrIgnore(dependency)) {
                            ClassDescriptor dependencyDescriptor = session.getDescriptor(dependency);
                            // PERF: Get the descriptor query, to avoid extra query creation.
                            DeleteObjectQuery deleteQuery = dependencyDescriptor.getQueryManager().getDeleteQuery();
                            if (deleteQuery == null) {
                                deleteQuery = new DeleteObjectQuery();
                                deleteQuery.setDescriptor(dependencyDescriptor);
                            } else {
                                // Ensure original query has been prepared.
                                deleteQuery.checkPrepare(session, deleteQuery.getTranslationRow());
                                deleteQuery = (DeleteObjectQuery)deleteQuery.clone();
                            }
                            deleteQuery.setIsExecutionClone(true);
                            deleteQuery.setObject(dependency);
                            session.executeQuery(deleteQuery);
                        }
                    }
                }
            }

            // CR#2660080 missing aboutToDelete event.
            // PERF: Avoid events if no listeners.
            if (eventManager.hasAnyEventListeners()) {
                DescriptorEvent event = new DescriptorEvent(DescriptorEventManager.AboutToDeleteEvent, this);
                event.setRecord(getModifyRow());
                eventManager.executeEvent(event);
            }

            if (QueryMonitor.shouldMonitor()) {
                QueryMonitor.incrementDelete(this);
            }
            int rowCount = 0;
            // If the object was/will be deleted from a cascade delete constraint, ignore it.
            if (isUnitOfWork && ((UnitOfWorkImpl)session).hasCascadeDeleteObjects()
                    && ((UnitOfWorkImpl)session).getCascadeDeleteObjects().contains(object)) {
                // Cascade delete does not check optimistic lock, assume ok.
                rowCount = 1;
            } else {
                rowCount = getQueryMechanism().deleteObject().intValue();
            }

            if (rowCount < 1) {
                if (session.hasEventManager()) {
                    session.getEventManager().noRowsModified(this, object);
                }
            }

            if (this.usesOptimisticLocking) {
                descriptor.getOptimisticLockingPolicy().validateDelete(rowCount, object, this);
            }

            commitManager.markPostModifyCommitInProgress(getObject());
            // Verify if deep shallow modify is turned on
            if (shouldCascadeParts()) {
                descriptor.getQueryManager().postDelete(this);
            }

            if ((descriptor.getHistoryPolicy() != null) && descriptor.getHistoryPolicy().shouldHandleWrites()) {
                descriptor.getHistoryPolicy().postDelete(this);
            }

            // PERF: Avoid events if no listeners.
            if (eventManager.hasAnyEventListeners()) {
                // Need to run post-delete selector if available
                eventManager.executeEvent(new DescriptorEvent(DescriptorEventManager.PostDeleteEvent, this));
            }

            if (!isUnitOfWork) {
                session.commitTransaction();
            }
            commitManager.markCommitCompleted(object);

            // CR3510313, avoid removing aggregate collections from cache (maintain cache is false).
            if (shouldMaintainCache()) {
                if (isUnitOfWork) {
                    ((UnitOfWorkImpl)session).addObjectDeletedDuringCommit(object, descriptor);
                } else {
                    session.getIdentityMapAccessorInstance().removeFromIdentityMap(getPrimaryKey(), descriptor.getJavaClass(), descriptor, object);
                }
            }
            return object;

        } catch (RuntimeException exception) {
            if (!isUnitOfWork) {
                session.rollbackTransaction();
            }
            commitManager.markCommitCompleted(object);
            throw exception;
        }
    }

    /**
     * PUBLIC:
     * Return if this is a delete object query.
     */
    @Override
    public boolean isDeleteObjectQuery() {
        return true;
    }

    /**
     * PUBLIC: (REQUIRED)
     * Set the object required for modification.
     */
    @Override
    public void setObject(Object object) {
        if (isPrepared()) {
            if (this.usesOptimisticLocking != shouldUseOptimisticLocking(object)) {
                setIsPrepared(false);
            }
        }
        super.setObject(object);
    }

    /**
     * INTERNAL:
     * Determines whether the query should use optimistic locking with the passed object.
     */
    protected boolean shouldUseOptimisticLocking(Object object) {
        if (this.descriptor.usesOptimisticLocking()) {
            if (object != null) {
                FetchGroupManager fetchGroupManager = this.descriptor.getFetchGroupManager();
                if (fetchGroupManager != null) {
                    FetchGroup fetchGroup = fetchGroupManager.getObjectFetchGroup(object);
                    if (fetchGroup == fetchGroupManager.getIdEntityFetchGroup()) {
                        return false;
                    }
                }
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * INTERNAL:
     * Indicating whether the query should use optimistic locking.
     */
    public boolean usesOptimisticLocking() {
        return this.usesOptimisticLocking;
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    @Override
    protected void prepare() {
        super.prepare();
        this.usesOptimisticLocking = shouldUseOptimisticLocking(this.object);
        if (this.name == null) {
            this.name = "delete" + this.descriptor.getJavaClass().getSimpleName();
        }
        getQueryMechanism().prepareDeleteObject();
    }

    /**
     * INTERNAL:
     * Set the properties needed to be cascaded into the custom query.
     * A custom query is set by the user, or used by default to allow caching of the prepared query.
     * In a unit of work the custom query is used directly, so this step is bypassed.
     */
    @Override
    protected void prepareCustomQuery(DatabaseQuery customQuery) {
        DeleteObjectQuery customDeleteQuery = (DeleteObjectQuery)customQuery;
        customDeleteQuery.setObject(getObject());
        customDeleteQuery.setObjectChangeSet(getObjectChangeSet());
        customDeleteQuery.setCascadePolicy(getCascadePolicy());
        customDeleteQuery.setShouldMaintainCache(shouldMaintainCache());
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session. In particular,
     * verify that the object is not null and contains a valid primary key.
     */
    @Override
    public void prepareForExecution() throws QueryException {
        super.prepareForExecution();

        // Set the translation row
        if ((this.translationRow == null) || this.translationRow.isEmpty()) {
            if (this.isFullRowRequired) {
                this.translationRow = this.descriptor.getObjectBuilder().buildRow(this.object, this.session, WriteType.UNDEFINED);
            } else {
                this.translationRow = this.descriptor.getObjectBuilder().buildRowForTranslation(this.object, this.session);
            }
        }

        // Add the write lock field if required
        if (this.usesOptimisticLocking) {
            this.descriptor.getOptimisticLockingPolicy().addLockValuesToTranslationRow(this);
        }
    }
}
