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

import java.util.Iterator;
import java.util.Vector;

import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.queries.DeleteAllQuery;
import org.eclipse.persistence.sessions.UnitOfWork;

public class DeleteAllQueryTestHelper {

    public static String execute(Session mainSession, Class referenceClass, Expression selectionExpression) {
        return execute(mainSession, referenceClass, selectionExpression, true);
    }

    public static String execute(Session mainSession, Class referenceClass, Expression selectionExpression, boolean shouldDeferExecutionInUOW) {
        return execute(mainSession, referenceClass, selectionExpression, shouldDeferExecutionInUOW, true);
    }

    // mainSession - the ServerSession used.
    // referenceClass - the reference class of DeleteAllQuery to be tested
    // selectionExpression - selection expression of DeleteAllQuery to be tested
    // shouldDeferExecutionInUOW==true causes deferring query execution until uow.commit;
    // shouldDeferExecutionInUOW==false causes immediate query execution;
    // shouldHandleChildren==true means the test will be executed not only with the specified class,
    // but also with all its subclasses.
    // Each test will test DeleteAllQuery with the specified reference class
    // and all its subclasses
    // Example: for Vehicle.class  9 DeleteAllQueries will be tested.
    // shouldHandleChildren==false means the test will be executed with the specified class only.
    //
    // For each DeleteAllQuery its results compared with one-by-one deletion:
    //  selectionCriteria is used to select objects and then delete them one-by-one (using uow.deleteObject);
    //  the results are saved and after compared with DeleteAllQuery results:
    //    both inCache and inDb comparison performed;
    //    both deleted and remained objects should be the same;
    public static String execute(Session mainSession, Class referenceClass, Expression selectionExpression, boolean shouldDeferExecutionInUOW, boolean handleChildren) {
        Class rootClass = referenceClass;
        ClassDescriptor descriptor = mainSession.getClassDescriptor(referenceClass);
        if(descriptor.hasInheritance()) {
            ClassDescriptor parentDescriptor = descriptor;
            while(!parentDescriptor.getInheritancePolicy().isRootParentDescriptor()) {
                parentDescriptor = parentDescriptor.getInheritancePolicy().getParentDescriptor();
            }
            rootClass = parentDescriptor.getJavaClass();
        }
        String errorMsg = execute(mainSession, referenceClass, selectionExpression, shouldDeferExecutionInUOW, handleChildren, rootClass);

        if(errorMsg.length() == 0) {
            return null;
        } else {
            return errorMsg;
        }
    }

    protected static String execute(Session mainSession, Class referenceClass, Expression selectionExpression, boolean shouldDeferExecutionInUOW, boolean handleChildren,
                                    Class rootClass) {
        String errorMsg = "";
        clearCache(mainSession);

        // first delete using the original TopLink approach - one by one.
        UnitOfWork uow = mainSession.acquireUnitOfWork();
        // mainSession could be a ServerSession
        Session session = uow.getParent();

        // Will need to bring the db back to its original state
        // so that comparison of the deletion result would be possible.
        ((AbstractSession)session).beginTransaction();

        Vector objectsToDelete = uow.readAllObjects(referenceClass, selectionExpression);

        ClassDescriptor descriptor = mainSession.getClassDescriptor(referenceClass);

        uow.deleteAllObjects(objectsToDelete);
        mainSession.logMessage("***delete one by one");
        uow.commit();

        Vector objectsLeftAfterOriginalDeletion = session.readAllObjects(rootClass);

        ((AbstractSession)session).rollbackTransaction();

        // now delete using DeleteAllQuery.
        clearCache(mainSession);

        // bring all objects into cache
        session.readAllObjects(rootClass);

        uow = mainSession.acquireUnitOfWork();
        // mainSession could be a ServerSession
        session = uow.getParent();

        // Will need to bring the db back to its original state
        // so that the in case thre are children descriptors
        // they would still have objects to work with.
        ((AbstractSession)session).beginTransaction();

        DeleteAllQuery query = new DeleteAllQuery(referenceClass, selectionExpression);
        query.setShouldDeferExecutionInUOW(shouldDeferExecutionInUOW);
        uow.executeQuery(query);
        mainSession.logMessage("***DeleteAllQuery for class " + referenceClass.getName());
        uow.commit();

        // verify that cache invalidation worked correctly:
        // deleted objects should've disappeared, others remain
        String classErrorMsg = "";
        for(int i=0; i < objectsToDelete.size(); i++) {
            Object deletedObject = session.readObject(objectsToDelete.elementAt(i));
            if(deletedObject != null) {
                classErrorMsg = classErrorMsg + "Deleted object "+ deletedObject +" is stil in cache; ";
                break;
            }
        }
        for(int i=0; i < objectsLeftAfterOriginalDeletion.size(); i++) {
            Object remainingObject = objectsLeftAfterOriginalDeletion.elementAt(i);
            Object remainingObjectRead = session.readObject(remainingObject);
            if(remainingObjectRead == null) {
                classErrorMsg = classErrorMsg + "Remaining object " + remainingObject +" is not in cache; ";
                break;
            }
        }

        // now let's verify that the objects were correctly deleted from the db
        clearCache(mainSession);
        // deleted objects should've disappeared, others remain
        for(int i=0; i < objectsToDelete.size(); i++) {
            Object deletedObject = session.readObject(objectsToDelete.elementAt(i));
            if(deletedObject != null) {
                classErrorMsg = classErrorMsg + "Deleted object "+ deletedObject + " is stil in db; ";
                break;
            }
        }
        for(int i=0; i < objectsLeftAfterOriginalDeletion.size(); i++) {
            Object remainingObject = objectsLeftAfterOriginalDeletion.elementAt(i);
            Object remainingObjectRead = session.readObject(remainingObject);
            if(remainingObjectRead == null) {
                classErrorMsg = classErrorMsg + "Remaining object " + remainingObject +" is not in db; ";
                break;
            }
        }

        ((AbstractSession)session).rollbackTransaction();

        if(classErrorMsg.length() > 0) {
            String className = referenceClass.getName();
            String shortClassName = className.substring(className.lastIndexOf('.') + 1);
            errorMsg = errorMsg + " " + shortClassName + ": " + classErrorMsg;
        }

        if(handleChildren) {
            if(descriptor.hasInheritance() && descriptor.getInheritancePolicy().hasChildren()) {
                Iterator it = descriptor.getInheritancePolicy().getChildDescriptors().iterator();
                while(it.hasNext()) {
                    ClassDescriptor childDescriptor = (ClassDescriptor)it.next();
                    Class childReferenceClass = childDescriptor.getJavaClass();
                    errorMsg += execute(mainSession, childReferenceClass, selectionExpression, shouldDeferExecutionInUOW, handleChildren, rootClass);
                }
            }
        }
        return errorMsg;
    }

    protected static void clearCache(Session mainSession) {
        mainSession.getIdentityMapAccessor().initializeAllIdentityMaps();
    }
}
