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

/**
 * <p><b>Purpose</b>:
 * Query used to delete a collection of objects.
 * This is used by mappings to delete all of their target objects in a single database call.
 * The SQL/SQLStatements must be provided.
 * <p>
 * DeleteAll can also be used with an Expression (or JPQL) to dynamically delete
 * a set of objects from the database, and invalidate them in the cache.
 *
 * <p><b>Responsibilities</b>:
 * <ul>
 * <li> Stores {@literal &} retrieves the objects to delete.
 * <li> Store the where clause used for the deletion.
 * </ul>
 *
 * @author Yvon Lavoie
 * @since TOPLink/Java 1.0
 */
public class DeleteAllQuery extends ModifyAllQuery {

    /** List containing objects to be deleted, these should be removed from the identity map after deletion. */
    protected List<Object> objects;

    /**
     * Defines if objects should be remove from the persistence context only (no database).
     * This is used if delete was already cascaded by the database.
     */
    protected boolean isInMemoryOnly;

    /**
     * PUBLIC:
     */
    public DeleteAllQuery() {
        super();
    }

    /**
     * PUBLIC:
     * Create a new delete all query for the class specified.
     */
    public DeleteAllQuery(Class referenceClass) {
        super(referenceClass);
    }

    /**
     * PUBLIC:
     * Create a new delete all query for the class and the selection criteria
     * specified.
     */
    public DeleteAllQuery(Class referenceClass, Expression selectionCriteria) {
        super(referenceClass, selectionCriteria);
    }

    /**
     * INTERNAL:
     * Return if objects should be remove from the persistence context only (no database).
     * This is used if delete was already cascaded by the database.
     */
    public boolean isInMemoryOnly() {
        return isInMemoryOnly;
    }

    /**
     * INTERNAL:
     * Set if objects should be remove from the persistence context only (no database).
     * This is used if delete was already cascaded by the database.
     */
    public void setIsInMemoryOnly(boolean isInMemoryOnly) {
        this.isInMemoryOnly = isInMemoryOnly;
    }

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

    /**
     * INTERNAL:
     * This method has to be broken.  If commit manager is not active either
     * an exception should be thrown (ObjectLevelModify case), or a transaction
     * should be started early and execute on parent if remote (dataModify case).
     * A modify query is NEVER executed on the parent, unless remote session.
     */
    @Override
    public Object executeInUnitOfWork(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException {
        if (this.objects != null) {
            if (unitOfWork.isAfterWriteChangesButBeforeCommit()) {
                throw ValidationException.illegalOperationForUnitOfWorkLifecycle(unitOfWork.getLifecycle(), "executeQuery(DeleteAllQuery)");
            }

            // This must be broken, see comment.
            if (!unitOfWork.getCommitManager().isActive()) {
                return unitOfWork.getParent().executeQuery(this, translationRow);
            }
            result = (Integer)super.execute(unitOfWork, translationRow);
            return result;
        } else {
            return super.executeInUnitOfWork(unitOfWork, translationRow);
        }
    }

    /**
     * INTERNAL:
     * Perform the work to delete a collection of objects.
     * This skips the optimistic lock check and should not called for objects using locking.
     * @exception  DatabaseException - an error has occurred on the database.
     * @return Integer the number of objects (rows) deleted.
     */
    @Override
    public Object executeDatabaseQuery() throws DatabaseException {
        // CR# 4286
        if (this.objects != null) {

            if (isExpressionQuery() && getSelectionCriteria() == null) {
                // DeleteAllQuery has objects so it *must* have selectionCriteria, too
                throw QueryException.deleteAllQuerySpecifiesObjectsButNotSelectionCriteria(getDescriptor(), this, this.objects.toString());
            }

            // Optimistic lock check not required because objects are deleted individually in that case.
            try {
                this.session.beginTransaction();

                // Need to run pre-delete selector if available.
                // PERF: Avoid events if no listeners.
                if (this.descriptor.getEventManager().hasAnyEventListeners()) {
                    for (Object object : this.objects) {
                        DescriptorEvent event = new DescriptorEvent(object);
                        event.setEventCode(DescriptorEventManager.PreDeleteEvent);
                        event.setSession(this.session);
                        event.setQuery(this);
                        this.descriptor.getEventManager().executeEvent(event);
                    }
                }

                if (this.isInMemoryOnly) {
                    result = Integer.valueOf(0);
                } else {
                    result = this.queryMechanism.deleteAll();
                }

                // Need to run post-delete selector if available.
                // PERF: Avoid events if no listeners.
                if (this.descriptor.getEventManager().hasAnyEventListeners()) {
                    for (Object object : this.objects) {
                        DescriptorEvent event = new DescriptorEvent(object);
                        event.setEventCode(DescriptorEventManager.PostDeleteEvent);
                        event.setSession(this.session);
                        event.setQuery(this);
                        this.descriptor.getEventManager().executeEvent(event);
                    }
                }

                if (shouldMaintainCache()) {
                    // remove from the cache.
                    for (Object deleted : this.objects) {
                        if (this.session.isUnitOfWork()) {
                            //BUG #2612169: Unwrap is needed
                            deleted = this.descriptor.getObjectBuilder().unwrapObject(deleted, getSession());
                            ((UnitOfWorkImpl)this.session).addObjectDeletedDuringCommit(deleted, this.descriptor);
                        } else {
                            this.session.getIdentityMapAccessor().removeFromIdentityMap(deleted);
                        }
                    }
                }

                this.session.commitTransaction();

            } catch (RuntimeException exception) {
                this.session.rollbackTransaction();
                throw exception;
            }
        } else {
            if (this.isInMemoryOnly) {
                result = Integer.valueOf(0);
            } else {
                result = this.queryMechanism.deleteAll();// fire the SQL to the database
            }
            mergeChangesIntoSharedCache();
        }

        return result;
    }

    /**
     * INTERNAL:
     * Delete all queries are executed specially to avoid cloning and ensure preparing.
     */
    public void executeDeleteAll(AbstractSession session, AbstractRecord translationRow, Vector objects) throws DatabaseException {
        this.checkPrepare(session, translationRow);
        DeleteAllQuery queryToExecute = (DeleteAllQuery)clone();

        // Then prepare for the single execution.
        queryToExecute.setTranslationRow(translationRow);
        queryToExecute.setSession(session);
        queryToExecute.setObjects(objects);
        queryToExecute.prepareForExecution();
        queryToExecute.executeDatabaseQuery();
    }

    /**
     * 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(){
        // 364001 - Do not return redirector if objects list is null.
        if (objects == null) {
            return null;
        }

        return descriptor.getDefaultDeleteObjectQueryRedirector();
    }


    /**
     * PUBLIC:
     * Return the objects that are to be deleted
     */
    public List<Object> getObjects() {
        return objects;
    }

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

        if (getReferenceClass() == null) {
            throw QueryException.referenceClassMissing(this);
        }

        if (getDescriptor() == null) {
            ClassDescriptor referenceDescriptor = getSession().getDescriptor(getReferenceClass());
            if (referenceDescriptor == null) {
                throw QueryException.descriptorIsMissing(getReferenceClass(), this);
            }
            setDescriptor(referenceDescriptor);
        }

        if (getDescriptor().isAggregateDescriptor()) {
            throw QueryException.aggregateObjectCannotBeDeletedOrWritten(getDescriptor(), this);
        }

        getQueryMechanism().prepareDeleteAll();
    }

    /**
     * PUBLIC (REQUIRED):
     * Set the objects to be deleted.
     * Also REQUIRED is a selection criteria or SQL string that performs the deletion of the objects.
     * This does not generate the SQL call from the deleted objects.
     * <p>
     * List objects used as an indicator of one of two possible
     * ways the query may behave:
     * <p> objects != null - the "old" functionality used by OneToMany mapping
     *     objects deleted from the cache, either selection expression or custom sql
     *     should be provided for deletion from db;
     * <p> objects == null - the "new" functionality (on par with UpdateAllQuery)
     *     the cache is either left alone or in-memory query finds the cached objects to be deleted,
     *     and these objects are invalidated in cache.
     * <p>
     * Note that empty objects is still objects != case.
     *     Signal that no cache altering is required.
     *     Used by AggregationCollectionMapping and OneToManyMapping in case they use indirection
     *     and the ValueHolder has not been instantiated.
     */
    public void setObjects(List<Object> objectCollection) {
        this.objects = objectCollection;
    }
}
