/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */

package org.apache.jdo.tck.query.delete;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;
import javax.jdo.listener.DeleteLifecycleListener;
import javax.jdo.listener.InstanceLifecycleEvent;
import javax.jdo.listener.StoreLifecycleListener;

import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.company.CompanyModelReader;
import org.apache.jdo.tck.pc.company.Department;
import org.apache.jdo.tck.pc.company.Employee;
import org.apache.jdo.tck.pc.company.Person;
import org.apache.jdo.tck.pc.company.Project;
import org.apache.jdo.tck.pc.mylib.MylibReader;
import org.apache.jdo.tck.pc.mylib.PrimitiveTypes;
import org.apache.jdo.tck.query.QueryElementHolder;
import org.apache.jdo.tck.query.QueryTest;
import org.apache.jdo.tck.util.BatchTestRunner;
import org.apache.jdo.tck.util.ConversionHelper;

/**
 *<B>Title:</B> Delete Persistent All.
 *<BR>
 *<B>Keywords:</B> query
 *<BR>
 *<B>Assertion ID:</B> A14.8-4
 *<BR>
 *<B>Assertion Description: </B>
 * Dirty instances of affected classes are first flushed to the datastore. 
 * Instances already in the cache when deleted via these methods 
 * or brought into the cache as a result of these methods 
 * undergo the life cycle transitions as if deletePersistent 
 * had been called on them. 
 * That is, if an affected class implements the DeleteCallback interface, 
 * the instances to be deleted are instantiated in memory and 
 * the jdoPreDelete method is called prior 
 * to deleting the instance in the datastore. 
 * If any LifecycleListener instances are registered with affected classes, 
 * these listeners are called for each deleted instance. 
 * Before returning control to the application, 
 * instances of affected classes in the cache are refreshed 
 * by the implementation so their status in the cache reflects 
 * whether they were deleted from the datastore.
 */
public class DeleteCallback extends QueryTest {

    /** */
    private static final String ASSERTION_FAILED = 
        "Assertion A14.8-4 (DeleteCallback) failed: ";
    
    /** 
     * The array of valid queries which may be executed as 
     * single string queries and as API queries.
     */
    private static final QueryElementHolder[] VALID_QUERIES = {
        new QueryElementHolder(
        /*UNIQUE*/      null,
        /*RESULT*/      null, 
        /*INTO*/        null, 
        /*FROM*/        Person.class,
        /*EXCLUDE*/     null,
        /*WHERE*/       null,
        /*VARIABLES*/   null,
        /*PARAMETERS*/  null,
        /*IMPORTS*/     null,
        /*GROUP BY*/    null,
        /*ORDER BY*/    null,
        /*FROM*/        null,
        /*TO*/          null),
        new QueryElementHolder(
        /*UNIQUE*/      null,
        /*RESULT*/      null, 
        /*INTO*/        null, 
        /*FROM*/        PrimitiveTypes.class,
        /*EXCLUDE*/     null,
        /*WHERE*/       null,
        /*VARIABLES*/   null,
        /*PARAMETERS*/  null,
        /*IMPORTS*/     null,
        /*GROUP BY*/    null,
        /*ORDER BY*/    null,
        /*FROM*/        null,
        /*TO*/          null)
    };
    
    /** 
     * The expected results of valid queries.
     */
    private List[] expectedResult = {
            getTransientCompanyModelInstancesAsList(new String[]{
                    "emp1", "emp2", "emp3", "emp4", "emp5"}),
            getTransientMylibInstancesAsList(new String[]{
                    "primitiveTypesPositive", 
                    "primitiveTypesNegative",
                    "primitiveTypesCharacterStringLiterals"})
    };
            
    /**
     * The <code>main</code> is called when the class
     * is directly executed from the command line.
     * @param args The arguments passed to the program.
     */
    public static void main(String[] args) {
        BatchTestRunner.run(DeleteCallback.class);
    }
    
    /** */
    public void testRelationshipsAPI() {
        queryUpdateDeleteVerify(0, false, "middlename");
    }
    
    /** */
    public void testRelationshipsSingleString() {
        queryUpdateDeleteVerify(0, true, "middlename");
    }
    
    /** */
    public void testNoRelationshipsAPI() {
        queryUpdateDeleteVerify(1, false, "stringNull");
    }
    
    /** */
    public void testNoRelationshipsSingleString() {
        queryUpdateDeleteVerify(1, true, "stringNull");
    }

    /**
     * @see org.apache.jdo.tck.JDO_Test#localSetUp()
     */
    @Override
    protected void localSetUp() {
        addTearDownClass(CompanyModelReader.getTearDownClasses());
        addTearDownClass(MylibReader.getTearDownClasses());
        loadAndPersistCompanyModel(getPM());
        loadAndPersistMylib(getPM());
    }
    
    /**
     * Adds a lifecycle listener to the persistence manager.
     * Converts the query element holder instance refered to by argument
     * <code>index</code> to a JDO query instance based on argument
     * <code>asSingleString</code>.
     * Executes the query instance and marks all queried pc instances as dirty 
     * by calling {@link JDOHelper#makeDirty(java.lang.Object, java.lang.String)}.
     * Passes argument <code>fieldName</code> to that call. 
     * Afterwards, calls {@link Query#deletePersistentAll()}, and
     * verifies the lifecycle callbacks and the lifecycle states.
     * @param index the index of the query element holder instance
     * @param fieldName the field name passed as argument to
     * {@link JDOHelper#makeDirty(java.lang.Object, java.lang.String)
     * @param asSingleString determines if the query is executed as
     * single string query or as API query.
     */
    private void queryUpdateDeleteVerify(int index, 
            boolean asSingleString, String fieldName) {
        PersistenceManager pm = getPM();
        Transaction transaction = pm.currentTransaction();
        transaction.begin();
        try
        {
            LifecycleVerifier lifecycleVerifier;
            Query query = asSingleString ? 
                    VALID_QUERIES[index].getSingleStringQuery(pm) :
                        VALID_QUERIES[index].getAPIQuery(pm);
                    
            Collection result = executeQuery(query, index, asSingleString);
            try {
                lifecycleVerifier = new LifecycleVerifier(result);
                pm.addInstanceLifecycleListener(lifecycleVerifier, 
                        new Class[]{VALID_QUERIES[index].getCandidateClass()});
                updateInstances(result, fieldName);
                deleteInstances(query, index, asSingleString, result.size());
            } finally
            {
                query.close(result);
            }
            
            lifecycleVerifier.verifyCallbacksAndStates();
        } finally {
            if (transaction.isActive()) {
                transaction.rollback();
            }
        }
    }
    
    /**
     * Executes the given query, checks and returns the query result.
     * Note: This mthod does not close the query result.
     * @param query the query.
     * @param index the index of the query element holder instance
     * which was used to created the given query.
     * @param asSingleString indicates if the given query was created 
     * using API methods or if it was created by a single string.
     * @return the query result.
     */
    private Collection executeQuery(Query query, 
            int index, boolean asSingleString) {
        if (logger.isDebugEnabled()) {
            if (asSingleString) {
                logger.debug("Executing single string query: " + 
                        VALID_QUERIES[index]);
            } else {
                logger.debug("Executing API query: " + 
                        VALID_QUERIES[index]);
            }
        }
        
        Collection result = (Collection) query.execute();
        
        if (logger.isDebugEnabled()) {
            logger.debug("Query result: " + ConversionHelper.
                convertObjectArrayElements(result));
        }
        
        checkQueryResultWithoutOrder(ASSERTION_FAILED, result, expectedResult[index]);
        return result;
    }
    
    /**
     * Makes all instances in the given collection dirty.
     * If instances are employees, then all relationships are cleared. 
     * @param instances the instances
     * @param fieldName the field name passed as argument to
     * {@link JDOHelper#makeDirty(java.lang.Object, java.lang.String)
     */
    private void updateInstances(Collection instances, String fieldName) {
        for (Iterator i = instances.iterator(); i.hasNext(); ) {
            Object pc = i.next();
            
            // clear employee relationships
            if (pc instanceof Employee) {
                Employee employee = (Employee) pc;
                if (employee.getDentalInsurance() != null) {
                    employee.getDentalInsurance().setEmployee(null);
                }
                if (employee.getMedicalInsurance() != null) {
                    employee.getMedicalInsurance().setEmployee(null);
                }
                if (employee.getDepartment() != null) {
                    ((Department)employee.getDepartment()).removeEmployee(employee);
                }
                if (employee.getFundingDept() != null) {
                    ((Department)employee.getFundingDept()).removeEmployee(employee);
                }
                if (employee.getManager() != null) {
                    ((Employee)employee.getManager()).removeFromTeam(employee);
                }
                if (employee.getMentor() != null) {
                    employee.getMentor().setProtege(null);
                }
                if (employee.getProtege() != null) {
                    employee.getProtege().setMentor(null);
                }
                if (employee.getHradvisor() != null) {
                    ((Employee)employee.getHradvisor()).removeAdvisee(employee);
                }
                if (employee.getReviewedProjects() != null) {
                    for (Iterator it=employee.getReviewedProjects().iterator(); 
                            it.hasNext(); ) {
                        Project other = (Project) it.next();
                        other.removeReviewer(employee);
                    }
                }
                if (employee.getProjects() != null) {
                    for (Iterator it=employee.getProjects().iterator(); 
                            it.hasNext(); ) {
                        Project other = (Project) it.next();
                        other.removeMember(employee);
                    }
                }
                if (employee.getTeam() != null) {
                    for (Iterator it=employee.getTeam().iterator(); it.hasNext(); ) {
                        Employee other = (Employee) it.next();
                        other.setManager(null);
                    }
                }
                if (employee.getHradvisees() != null) {
                    for (Iterator it=employee.getHradvisees().iterator(); it.hasNext(); ) {
                        Employee other = (Employee) it.next();
                        other.setHradvisor(employee);
                    }
                }
            }
            
            // make the instance dirty.
            if (logger.isDebugEnabled()) {
                logger.debug("Calling JDOHelper.makeDirty(" + 
                        pc + ", \"" + fieldName + "\")");
            }
            JDOHelper.makeDirty(pc, fieldName);
        }
    }

    /**
     * Calls {@link Query#deletePersistentAll()} on the given query.
     * @param query the query.
     * @param index the index of the query element holder instance
     * which was used to created the given query.
     * @param asSingleString indicates if the given query was created 
     * using API methods or if it was created by a single string.
     * @param expectedNumberOfDeletedInstances the expected number 
     * of deleted instances.
     */
    private void deleteInstances(Query query, int index, 
            boolean asSingleString, int expectedNumberOfDeletedInstances) {
        if (logger.isDebugEnabled()) {
            if (asSingleString) {
                logger.debug("Deleting persistent by single string query: " + 
                        VALID_QUERIES[index]);
            } else {
                logger.debug("Deleting persistent by API query: " + 
                        VALID_QUERIES[index]);
            }
        }

        long nr = query.deletePersistentAll();
        
        if (logger.isDebugEnabled()) {
            logger.debug(nr + " objects deleted.");
        }
        
        if (nr != expectedNumberOfDeletedInstances) {
            fail(ASSERTION_FAILED, "deletePersistentAll returned " + nr +
                    ", expected is " + expectedNumberOfDeletedInstances + 
                    ". Query: " + VALID_QUERIES[index]);
        }
    }
    
    /**
     * A lifecycle listener which may be added to persistence managers.
     * Gathers delete events and store events and keeps those
     * in a list. 
     * Method {@link LifecycleVerifier#verifyCallbacksAndStates()}
     * may be called to check if the right events have been called
     * on all expected instances.
     * The expected instances are passed through
     * {@link LifecycleVerifier#LifecycleVerifier(Collection).
     */
    private class LifecycleVerifier
        implements DeleteLifecycleListener, StoreLifecycleListener {
        
        /** The oids of expected pc instances. */
        private Collection expectedOids = new HashSet();
        
        /** The list of events. */
        private List events = new ArrayList();
        
        /**
         * Argument <code>expectedPCInstances</code> holds pc instances
         * which are expected to be sources of events.
         * @param expectedPCInstances the pc instances
         * which are expected to be sources of events.
         */
        public LifecycleVerifier(Collection expectedPCInstances) {
            for (Iterator i = expectedPCInstances.iterator(); i.hasNext(); ) {
                this.expectedOids.add(JDOHelper.getObjectId(i.next()));
            }
        }
        
        /**
         * Verifies if the right events have been called for all
         * expected pc instances.
         * All store events must have been fired before the
         * first delete event has been fired.
         * Furthermore, checks if pc instances kept in 
         * delete events have state persistent-deleted.
         * The test case fails if one of these conditions
         * is violated. 
         */
        public void verifyCallbacksAndStates() {
            if (logger.isDebugEnabled()) {
                logger.debug("Verifying callbacks and states.");
            }
            // The two collections are filled iterating through the list of 
            // events. Finally, they are compared against field expectedOids.
            // Note: Set implementations are used instead of list 
            // implementations to eliminate duplicates. Duplicates may occur
            // if multiple updates or deletions are executed for the same
            // pc instances.
            Collection oidsOfDeletedInstances = new HashSet();
            Collection oidsOfUpdateInstances = new HashSet();
            
            boolean hasDeleteEventBeenPassed = false;
            int size = events.size();
            for (int i = 0; i < size; i++) {
                InstanceLifecycleEvent event = 
                    (InstanceLifecycleEvent) this.events.get(i);
                Object source = event.getSource();
                int eventType = event.getEventType();
                if (eventType == InstanceLifecycleEvent.DELETE) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Verifying delete event on " + 
                                JDOHelper.getObjectId(source));
                    }
                    hasDeleteEventBeenPassed = true;
                    if (!JDOHelper.isDeleted(source)) {
                        fail(ASSERTION_FAILED, 
                                "PC instance must have persistent deleted " +
                                "state: " + source);
                    }
                    oidsOfDeletedInstances.add(JDOHelper.getObjectId(source));
                } else if (eventType == InstanceLifecycleEvent.STORE) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Verifying store event on " + 
                                JDOHelper.getObjectId(source));
                    }
                    
                    if (hasDeleteEventBeenPassed) {
                        fail(ASSERTION_FAILED, 
                                "PC instances must not be flushed " +
                                "after delete has been executed.");
                    }
                    oidsOfUpdateInstances.add(JDOHelper.getObjectId(source));
                }
            }
            
            if (!equalsCollection(oidsOfDeletedInstances, 
                    this.expectedOids)) {
                String lf = System.getProperty("line.separator");
                fail(ASSERTION_FAILED, "Got delete events for oids " + 
                        oidsOfDeletedInstances + '.' + lf +
                        "Expected deleted events for oids " + 
                        this.expectedOids + '.');
            } else if (!oidsOfUpdateInstances.containsAll(this.expectedOids)) {
                String lf = System.getProperty("line.separator");
                fail(ASSERTION_FAILED, "Got store events for oids " +  
                        oidsOfUpdateInstances + '.' + lf +
                        "Expected store events for oids " + 
                        this.expectedOids + '.');
            }
        }
        
        /**
         * @see DeleteLifecycleListener#preDelete(javax.jdo.listener.InstanceLifecycleEvent)
         */
        public void preDelete(InstanceLifecycleEvent event) {
            if (logger.isDebugEnabled()) {
                logger.debug("preDelete event: " + 
                        JDOHelper.getObjectId(event.getSource()));
            }
        }

        /**
         * @see DeleteLifecycleListener#postDelete(javax.jdo.listener.InstanceLifecycleEvent)
         */
        public void postDelete(InstanceLifecycleEvent event) {
            this.events.add(event);
            if (logger.isDebugEnabled()) {
                logger.debug("postDelete event: " + 
                        JDOHelper.getObjectId(event.getSource()));
            }
        }

        /**
         * @see StoreLifecycleListener#preStore(javax.jdo.listener.InstanceLifecycleEvent)
         */
        public void preStore(InstanceLifecycleEvent event) {
            if (logger.isDebugEnabled()) {
                logger.debug("preStore event: " + 
                        JDOHelper.getObjectId(event.getSource()));
            }
        }
        
        /**
         * @see StoreLifecycleListener#postStore(javax.jdo.listener.InstanceLifecycleEvent)
         */
        public void postStore(InstanceLifecycleEvent event) {
            this.events.add(event);
            if (logger.isDebugEnabled()) {
                logger.debug("postStore event: " + 
                        JDOHelper.getObjectId(event.getSource()));
            }
        }
    }
}
