/*
 * 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.ArrayList;
import java.util.List;
import javax.jdo.JDOHelper;
import javax.jdo.listener.AttachLifecycleListener;
import javax.jdo.listener.ClearLifecycleListener;
import javax.jdo.listener.CreateLifecycleListener;
import javax.jdo.listener.DeleteLifecycleListener;
import javax.jdo.listener.DetachLifecycleListener;
import javax.jdo.listener.DirtyLifecycleListener;
import javax.jdo.listener.InstanceLifecycleEvent;
import javax.jdo.listener.LoadLifecycleListener;
import javax.jdo.listener.StoreLifecycleListener;
import org.apache.jdo.tck.JDO_Test;

/**
 * <B>Title:</B> Abstract test AbstractInstanceLifecycleListener <br>
 * <B>Keywords:</B> LifeCycleListener lifecycle listener callback <br>
 * <B>Assertion IDs:</B> A12.15-1, A12.15-2, A12.15-3, A12.15-4, A12.15-5, A12.15-6, A12.15-7,
 * A12.15-8, A12.15-9, A12.15-10, A12.15-11, A12.15-12, A12.15-13, A12.15-14, <br>
 * <B>Assertion Description: </B> A12.15-1 void postCreate(InstanceLifecycleEvent event); This
 * method is called whenever a persistent instance is created, during makePersistent. It is called
 * after the instance transitions to persistent-new. A12.15-2 void postLoad(InstanceLifecycleEvent
 * event); This method is called whenever a persistent instance is loaded. It is called after the
 * jdoPostLoad method is invoked on the instance. A12.15-3 void preStore(InstanceLifecycleEvent
 * event); This method is called whenever a persistent instance is stored, for example during flush
 * or commit. It is called before the jdoPreStore method is invoked on the instance. A12.15-4 void
 * postStore(InstanceLifecycleEvent event); This method is called whenever a persistent instance is
 * stored, for example during flush or commit. It is called after the jdoPreStore method is invoked
 * on the instance. An object identity for a per?sistent-new instance must have been assigned to the
 * instance when this callback is invoked. A12.15-5 void preClear(InstanceLifecycleEvent event);
 * This method is called whenever a persistent instance is cleared, for example during
 * afterCompletion. It is called before the jdoPreClear method is invoked on the instance. A12.15-6
 * void postClear(InstanceLifecycleEvent event); This method is called whenever a persistent
 * instance is cleared, for example during afterCom?pletion. It is called after the jdoPreClear
 * method is invoked on the instance and the fields have been cleared by the JDO implementation.
 * 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. A12.15-9 void preDirty(InstanceLifecycleEvent event);
 * This method is called whenever a persistent clean instance is first made dirty, during an
 * operation that modifies the value of a persistent or transactional field. It is called before the
 * field value is changed. A12.15-10 void postDirty(InstanceLifecycleEvent event); This method is
 * called whenever a persistent clean instance is first made dirty, during an operation that
 * modifies the value of a persistent or transactional field. It is called after the field value was
 * changed. A12.15-11 void preDetach(InstanceLifecycleEvent event); This method is called before a
 * persistent instance is copied for detachment. A12.15-12 void postDetach(InstanceLifecycleEvent
 * event); This method is called whenever a persistent instance is copied for detachment. The source
 * instance is the detached copy; the target instance is the persistent instance. A12.15-13 void
 * preAttach(InstanceLifecycleEvent event); This method is called before a detached instance is
 * attached. The source instance is the detached instance]. A12.15-14 void
 * postAttach(InstanceLifecycleEvent event); This method is called after a detached instance is
 * attached. The source instance is the corresponding persistent instance in the cache; the target
 * instance is the detached instance.
 *
 * <p>This is the abstract base class for the lifecycle listener test classes. It contains
 * constants, variables, and methods used by each listener test class. This class implements the
 * setup and teardown methods used by each concrete test class.
 *
 * <p>This class also includes the listener base class that is extended by each specific listener.
 *
 * <p>The strategy of each test case is the same. A specific listener is implemented that responds
 * only to events for that specific test; a specific persistence-capable class is also implemented,
 * that responds only to callbacks for the specific test. A sequence of operations that stimulates
 * the callbacks is executed. During these operations, listener events and callbacks are collected
 * by the listener instance. Finally, the actual events and callbacks that were collected are
 * analyzed and differences are reported.
 */
public abstract class AbstractInstanceLifecycleListener extends JDO_Test {

  /** */
  protected static final String ASSERTION1_FAILED =
      "Assertion A12.15-1 (TestInstanceLifecycleListenerCreate) failed: ";

  protected static final String ASSERTION2_FAILED =
      "Assertion A12.15-2 (TestInstanceLifecycleListener) failed: ";
  protected static final String ASSERTION3_FAILED =
      "Assertion A12.15-3 (TestInstanceLifecycleListener) failed: ";
  protected static final String ASSERTION4_FAILED =
      "Assertion A12.15-4 (TestInstanceLifecycleListener) failed: ";
  protected static final String ASSERTION5_FAILED =
      "Assertion A12.15-5 (TestInstanceLifecycleListener) failed: ";
  protected static final String ASSERTION6_FAILED =
      "Assertion A12.15-6 (TestInstanceLifecycleListener) failed: ";
  protected static final String ASSERTION7_FAILED =
      "Assertion A12.15-7 (TestInstanceLifecycleListenerDelete) failed: ";
  protected static final String ASSERTION8_FAILED =
      "Assertion A12.15-8 (TestInstanceLifecycleListenerDelete) failed: ";
  protected static final String ASSERTION9_FAILED =
      "Assertion A12.15-9 (TestInstanceLifecycleListener) failed: ";
  protected static final String ASSERTION10_FAILED =
      "Assertion A12.15-10 (TestInstanceLifecycleListener) failed: ";
  protected static final String ASSERTION11_FAILED =
      "Assertion A12.15-11 (TestInstanceLifecycleListener) failed: ";
  protected static final String ASSERTION12_FAILED =
      "Assertion A12.15-12 (TestInstanceLifecycleListener) failed: ";
  protected static final String ASSERTION13_FAILED =
      "Assertion A12.15-13 (TestInstanceLifecycleListener) failed: ";
  protected static final String ASSERTION14_FAILED =
      "Assertion A12.15-14 (TestInstanceLifecycleListener) failed: ";

  /**
   * The listener to be used for the test. This method is implemented by the subclasses to use the
   * proper listener.
   *
   * @return listener
   */
  protected abstract InstanceLifecycleListenerImpl getListener();

  /**
   * The classes to be used for the test. This method is implemented by the subclasses to use the
   * proper classes. The classes returned by this method are used for two purposes: they are used to
   * register listeners; and they are used as the teardown classes whose instances are removed from
   * the datastore at the end of the test.
   *
   * @return classes
   */
  protected abstract Class<?>[] getPersistentClasses();

  /** Register a new InstanceLifecycleListenerImpl with the PersistenceManager. */
  protected void addListener() {
    getPM();
    pm.addInstanceLifecycleListener(getListener(), getPersistentClasses());
  }

  /** Unregister the InstanceLifecycleListenerImpl with the PersistenceManager. */
  protected void removeListener() {
    getPM();
    pm.removeInstanceLifecycleListener(getListener());
  }

  /** Set up for lifecycle tests: Register the LifecycleListener; add PCPoint to tearDownClasses. */
  @Override
  protected void localSetUp() {
    addListener();
    addTearDownClass(getPersistentClasses());
  }

  /** Clean up after lifecycle tests: Unregister the LifecycleListener. */
  @Override
  protected void localTearDown() {
    removeListener(); // no callbacks for teardown
    super.localTearDown();
  }

  /**
   * The LifeCycleListener to be registered with the PersistenceManager. This is the base class that
   * is extended by each test.
   */
  protected abstract static class InstanceLifecycleListenerImpl
      implements AttachLifecycleListener,
          ClearLifecycleListener,
          CreateLifecycleListener,
          DeleteLifecycleListener,
          DetachLifecycleListener,
          DirtyLifecycleListener,
          LoadLifecycleListener,
          StoreLifecycleListener {

    protected InstanceLifecycleListenerImpl() {}

    protected Object expectedSource = null;
    protected Object expectedTarget = null;

    public void setExpectedSource(Object source) {
      expectedSource = source;
    }

    public void setExpectedTarget(Object target) {
      expectedTarget = target;
    }

    /**
     * This is the list names of locations for listener events and callbacks. Each instance of an
     * event or callback has a specific name that is associated with the value. The values are used
     * during collection of events and both names and values are used for reporting results.
     */
    private static final List<String> locations = new ArrayList<>();

    /**
     * These are indexes into the sequence array. Each index represents the position in the sequence
     * array for the corresponding callback or listener event.
     */
    public static final int PRE_ATTACH_CALLBACK;

    public static final int POST_ATTACH_CALLBACK;
    public static final int PRE_ATTACH_LISTENER;
    public static final int POST_ATTACH_LISTENER;
    public static final int PRE_CLEAR_CALLBACK;
    public static final int PRE_CLEAR_LISTENER;
    public static final int POST_CLEAR_LISTENER;
    public static final int POST_CREATE_LISTENER;
    public static final int PRE_DELETE_CALLBACK;
    public static final int PRE_DELETE_LISTENER;
    public static final int POST_DELETE_LISTENER;
    public static final int PRE_DETACH_CALLBACK;
    public static final int POST_DETACH_CALLBACK;
    public static final int PRE_DETACH_LISTENER;
    public static final int POST_DETACH_LISTENER;
    public static final int PRE_DIRTY_LISTENER;
    public static final int POST_DIRTY_LISTENER;
    public static final int POST_LOAD_CALLBACK;
    public static final int POST_LOAD_LISTENER;
    public static final int PRE_STORE_CALLBACK;
    public static final int PRE_STORE_LISTENER;
    public static final int POST_STORE_LISTENER;

    /*
     * Initialize the list of names and the associated values. For each
     * listener event and callback, add the name and then assign the value.
     */
    static {
      int index = 0;
      locations.add("PRE_ATTACH_LISTENER");
      PRE_ATTACH_LISTENER = index++;
      locations.add("PRE_ATTACH_CALLBACK");
      PRE_ATTACH_CALLBACK = index++;
      locations.add("POST_ATTACH_CALLBACK");
      POST_ATTACH_CALLBACK = index++;
      locations.add("POST_ATTACH_LISTENER");
      POST_ATTACH_LISTENER = index++;
      locations.add("PRE_CLEAR_LISTENER");
      PRE_CLEAR_LISTENER = index++;
      locations.add("PRE_CLEAR_CALLBACK");
      PRE_CLEAR_CALLBACK = index++;
      locations.add("POST_CLEAR_LISTENER");
      POST_CLEAR_LISTENER = index++;
      locations.add("POST_CREATE_LISTENER");
      POST_CREATE_LISTENER = index++;
      locations.add("PRE_DELETE_LISTENER");
      PRE_DELETE_LISTENER = index++;
      locations.add("PRE_DELETE_CALLBACK");
      PRE_DELETE_CALLBACK = index++;
      locations.add("POST_DELETE_LISTENER");
      POST_DELETE_LISTENER = index++;
      locations.add("POST_DETACH_CALLBACK");
      POST_DETACH_CALLBACK = index++;
      locations.add("PRE_DETACH_LISTENER");
      PRE_DETACH_LISTENER = index++;
      locations.add("PRE_DETACH_CALLBACK");
      PRE_DETACH_CALLBACK = index++;
      locations.add("POST_DETACH_LISTENER");
      POST_DETACH_LISTENER = index++;
      locations.add("PRE_DIRTY_LISTENER");
      PRE_DIRTY_LISTENER = index++;
      locations.add("POST_DIRTY_LISTENER");
      POST_DIRTY_LISTENER = index++;
      locations.add("POST_LOAD_CALLBACK");
      POST_LOAD_CALLBACK = index++;
      locations.add("POST_LOAD_LISTENER");
      POST_LOAD_LISTENER = index++;
      locations.add("PRE_STORE_LISTENER");
      PRE_STORE_LISTENER = index++;
      locations.add("PRE_STORE_CALLBACK");
      PRE_STORE_CALLBACK = index++;
      locations.add("POST_STORE_LISTENER");
      POST_STORE_LISTENER = index++;
    }

    private final int[] actual = new int[locations.size()];

    /** Track the current sequence of callbacks. */
    private int current = 0;

    public void notifyEvent(int event) {
      actual[event] = ++current;
    }

    /**
     * Initialize the expected ordering of callbacks and listeners. Each entry in the sequence is
     * one of the PRE_ or POST_XXX_LISTENER or _CALLBACK above. The order in the sequence is the
     * expected calling order.
     */
    private static int[] newExpected(int[] sequence) {
      int order = 0;
      int[] result = new int[locations.size()];
      for (int j : sequence) {
        result[j] = ++order;
      }
      return result;
    }

    /** The error message buffer to report exceptions. */
    protected final StringBuffer messages = new StringBuffer();

    protected void checkEventType(String where, int expected, int actual) {
      if (expected != actual) {
        messages.append(
            where
                + "wrong event type: "
                + "expected <"
                + expected
                + ">, actual <"
                + actual
                + ">\n");
      }
    }

    protected void checkEventSource(String where, Object eventSource) {
      if (expectedSource != eventSource) {
        messages.append(
            where
                + "wrong event source: "
                + "expected <"
                + expectedSource
                + ">, actual <"
                + eventSource
                + ">\n");
      }
    }

    protected void checkEventTarget(String where, Object eventTarget) {
      if (expectedTarget != eventTarget) {
        messages.append(
            where
                + "wrong event target: "
                + "expected <"
                + expectedTarget
                + ">, actual <"
                + eventTarget
                + ">\n");
      }
    }

    protected void checkTrue(String where, boolean condition) {
      if (!condition) {
        messages.append(where + "was not true.\n");
      }
    }

    protected void checkSame(String where, Object expected, Object actual) {
      if (expected != actual) {
        messages.append(where + "expected <" + expected + ">, actual <" + actual + ">\n");
      }
    }

    protected void checkPersistent(String where, Object obj) {
      if (!JDOHelper.isPersistent(obj)) {
        messages.append(where + "object should be persistent.\n");
      }
    }

    protected void checkNotPersistent(String where, Object obj) {
      if (JDOHelper.isPersistent(obj)) {
        messages.append(where + "object should not be persistent.\n");
      }
    }

    protected void checkDirty(String where, Object obj) {
      if (!JDOHelper.isDirty(obj)) {
        messages.append(where + "object should be dirty.\n");
      }
    }

    protected void checkNotDirty(String where, Object obj) {
      if (JDOHelper.isDirty(obj)) {
        messages.append(where + "object should not be dirty.\n");
      }
    }

    protected void checkNew(String where, Object obj) {
      if (!JDOHelper.isNew(obj)) {
        messages.append(where + "object should be new.\n");
      }
    }

    protected void checkNotNew(String where, Object obj) {
      if (JDOHelper.isNew(obj)) {
        messages.append(where + "object should not be new.\n");
      }
    }

    protected void checkDeleted(String where, Object obj) {
      if (!JDOHelper.isDeleted(obj)) {
        messages.append(where + "object should be deleted.\n");
      }
    }

    protected void checkNotDeleted(String where, Object obj) {
      if (JDOHelper.isDeleted(obj)) {
        messages.append(where + "object should not be deleted.\n");
      }
    }

    /**
     * Verify the actual sequence of callbacks and listeners against the expected. Each of the
     * expected and actual are int arrays in which each listener and callback have one position in
     * the array and the value of the array at that position is the order, starting with 1, of the
     * callback. If the callback or listener was never invoked, the value is 0.
     *
     * @param where where
     * @param expected expected
     */
    public void verifyCallbacks(String where, int[] expected) {
      int[] expectedSequence = newExpected(expected);
      for (int index = 0; index < locations.size(); ++index) {
        if (expectedSequence[index] != actual[index]) {
          messages.append(
              "\nSequence verification failed for "
                  + locations.get(index)
                  + "; expected: <"
                  + expectedSequence[index]
                  + "> actual: <"
                  + actual[index]
                  + ">\n");
        }
      }
      if (messages.length() > 0) {
        fail(where + "\n" + messages);
      }
    }

    public void postAttach(InstanceLifecycleEvent event) {}

    public void postClear(InstanceLifecycleEvent event) {}

    public void postCreate(InstanceLifecycleEvent event) {}

    public void postDelete(InstanceLifecycleEvent event) {}

    public void postDetach(InstanceLifecycleEvent event) {}

    public void postDirty(InstanceLifecycleEvent event) {}

    public void postLoad(InstanceLifecycleEvent event) {}

    public void postStore(InstanceLifecycleEvent event) {}

    public void preAttach(InstanceLifecycleEvent event) {}

    public void preClear(InstanceLifecycleEvent event) {}

    public void preDelete(InstanceLifecycleEvent event) {}

    public void preDetach(InstanceLifecycleEvent event) {}

    public void preDirty(InstanceLifecycleEvent event) {}

    public void preStore(InstanceLifecycleEvent event) {}
  }
}
