/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     https://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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.tck.api.instancecallbacks;

import java.util.Date;
import javax.jdo.listener.DeleteCallback;
import javax.jdo.listener.InstanceLifecycleEvent;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Test TestInstanceLifecycleListenerDelete <br>
 * <B>Keywords:</B> LifeCycleListener deletePersistent preDelete postDelete <br>
 * <B>Assertion IDs:</B> A12.15-7 A12.15-8 <br>
 * <B>Assertion Description: </B> A12.15-7 void preDelete(InstanceLifecycleEvent event); This method
 * is called whenever a persistent instance is deleted, during deletePersistent. It is called before
 * the state transition and before the jdoPreDelete method is invoked on the instance. A12.15-8 void
 * postDelete(InstanceLifecycleEvent event); This method is called whenever a persistent instance is
 * deleted, during deletePersistent. It is called after the jdoPreDelete method is invoked on the
 * instance and after the state transition.
 */
public class InstanceLifecycleListenerDelete extends AbstractInstanceLifecycleListener {

  /** The InstanceLifecycleListener used for this test */
  private final InstanceLifecycleListenerImpl listener = new InstanceLifecycleListenerDeleteImpl();

  /** Return the listener. */
  protected InstanceLifecycleListenerImpl getListener() {
    return listener;
  }

  /** The persistent classes used for this test. */
  @SuppressWarnings("rawtypes")
  private static final Class<?>[] persistentClasses = new Class[] {PC.class};

  /** Return the persistent classes. */
  protected Class<?>[] getPersistentClasses() {
    return persistentClasses;
  }

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

  /**
   * This test creates a new persistent instance, and deletes it. The pre-delete listener,
   * pre-delete callback, and post-delete listener will be called.
   */
  public void testDelete() {

    // set up the persistent instance
    PC pc = new PC(listener);
    listener.setExpectedSource(pc);

    // deletePersistent should cause the delete listeners to be called
    getPM();
    pm.currentTransaction().begin();
    pm.makePersistent(pc);
    pm.deletePersistent(pc);
    pm.currentTransaction().commit();

    // now check the callback and listeners were called
    listener.verifyCallbacks(
        ASSERTION7_FAILED,
        (new int[] {
          InstanceLifecycleListenerImpl.PRE_DELETE_LISTENER,
          InstanceLifecycleListenerImpl.PRE_DELETE_CALLBACK,
          InstanceLifecycleListenerImpl.POST_DELETE_LISTENER
        }));
  }

  /** The LifeCycleListener to be registered with the PersistenceManager. */
  private static class InstanceLifecycleListenerDeleteImpl extends InstanceLifecycleListenerImpl {

    @Override
    public void preDelete(InstanceLifecycleEvent event) {
      notifyEvent(PRE_DELETE_LISTENER);
      checkEventType(ASSERTION7_FAILED, InstanceLifecycleEvent.DELETE, event.getEventType());
      checkEventSource(ASSERTION7_FAILED, event.getSource());
      checkPersistent(ASSERTION7_FAILED + " in preDelete, ", expectedSource);
      checkNotDeleted(ASSERTION7_FAILED + " in preDelete, ", expectedSource);
    }

    @Override
    public void postDelete(InstanceLifecycleEvent event) {
      notifyEvent(POST_DELETE_LISTENER);
      checkEventType(ASSERTION8_FAILED, InstanceLifecycleEvent.DELETE, event.getEventType());
      checkEventSource(ASSERTION8_FAILED, event.getSource());
      checkPersistent(ASSERTION8_FAILED + " in postDelete, ", expectedSource);
      checkDeleted(ASSERTION8_FAILED + " in postDelete, ", expectedSource);
    }
  }

  /** The persistence-capable class that implements the delete callback. */
  public static class PC implements DeleteCallback {
    transient InstanceLifecycleListenerImpl listener;
    int id;

    public PC() {}

    public PC(InstanceLifecycleListenerImpl listener) {
      id = counter++;
      this.listener = listener;
    }

    static int counter = (int) (new Date().getTime());

    public void jdoPreDelete() {
      if (listener != null) {
        listener.notifyEvent(InstanceLifecycleListenerImpl.PRE_DELETE_CALLBACK);
      }
    }
  }
}
