/*
 * 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.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
     *
     */
    @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();
            }

            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);
        }
    }
}
