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

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Iterator;
import javax.jdo.Extent;
import javax.jdo.JDOFatalException;
import javax.jdo.Transaction;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Test State Transitions <br>
 * <B>Keywords:</B> lifecycle <br>
 * <B>Assertion IDs:</B> A5.9-1 through A5.9-190 <B>Assertion Description: </B> All possible state
 * transistions are being tested in this test.
 */
public class StateTransitions extends JDO_Test {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertions A5.9-1 through A5.9-190 (StateTransitions) failed: ";

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

  private Transaction transaction;
  private int scenario;
  private int operation;
  private int current_state;
  private int expected_state;
  private int new_state;

  /** Operations that cause state changes */
  private static final int MAKEPERSISTENT = 0;

  private static final int DELETEPERSISTENT = 1;
  private static final int MAKETRANSACTIONAL = 2;
  private static final int MAKENONTRANSACTIONAL = 3;
  private static final int MAKETRANSIENT = 4;
  private static final int COMMITNORETAINVALUES = 5;
  private static final int COMMITRETAINVALUES = 6;
  private static final int ROLLBACKNORESTOREVALUES = 7;
  private static final int ROLLBACKRESTOREVALUES = 8;
  private static final int REFRESHDATASTORE = 9;
  private static final int REFRESHOPTIMISTIC = 10;
  private static final int EVICT = 11;
  private static final int READOUTSIDETX = 12;
  private static final int READOPTIMISTIC = 13;
  private static final int READDATASTORE = 14;
  private static final int WRITEOUTSIDETX = 15;
  private static final int WRITEINSIDETX = 16;
  private static final int RETRIEVEOUTSIDETX = 17;
  private static final int RETRIEVEINSIDETX = 18;
  private static final int DETACHALLONCOMMIT = 19;
  private static final int DETACHCOPYOUTSIDETXNTRTRU = 20;
  private static final int DETACHCOPYOUTSIDETXNTRFLS = 21;
  private static final int DETACHCOPYINSIDEDATASTORETX = 22;
  private static final int DETACHCOPYINSIDEOPTIMISTICTX = 23;
  private static final int SERIALIZEOUTSIDETX = 24;
  private static final int SERIALIZEDATASTORE = 25;
  private static final int SERIALIZEOPTIMISTIC = 26;

  private static final int NUM_OPERATIONS = 27;

  private static final String[] operations = {
    "makePersistent",
    "deletePersistent",
    "makeTransactional",
    "makeNontransactional",
    "makeTransient",
    "commit, retainValues=false",
    "commit, retainValues=true",
    "rollback, restoreValues=false",
    "rollback, restoreValues=true",
    "refresh with active datastore tx",
    "refresh with active optimistic tx",
    "evict",
    "read field outside tx",
    "read field with active optimistic tx",
    "read field with active datastore tx",
    "write field outside tx",
    "write field with active tx",
    "retrieve outside tx",
    "retrieve with active tx",
    "commit, detachAllOnCommit=true",
    "detachCopy outside tx with NontransactionalRead=true",
    "detachCopy outside tx with NontransactionalRead=false",
    "detachCopy with active datastore tx",
    "detachCopy with active optimistic tx",
    "serialize outside tx",
    "serialize with active datastore tx",
    "serialize with active optimistic tx"
  };

  /** Illegal state transitions */
  private static final int UNCHANGED = -1;

  private static final int ERROR = -2;
  private static final int IMPOSSIBLE = -3;
  private static final int NOT_APPLICABLE = -4;
  private static final int UNSPECIFIED = -5;

  /** State transitions */
  public static final int[][] transitions = { // [operation] [current state] = new state
    //  TRANSIENT,                      PERSISTENT_NEW,                     PERSISTENT_CLEAN,
    //  PERSISTENT_DIRTY,               HOLLOW,                             TRANSIENT_CLEAN,
    //  TRANSIENT_DIRTY,                PERSISTENT_NEW_DELETED,             PERSISTENT_DELETED,
    //  PERSISTENT_NONTRANSACTIONAL,    PERSISTENT_NONTRANSACTIONAL_DIRTY,  DETACHED_CLEAN,
    //  DETACHED_DIRTY

    // makePersistent
    {
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, PERSISTENT_NEW,
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, DETACHED_CLEAN,
      DETACHED_DIRTY
    },

    // deletePersistent
    {
      ERROR, PERSISTENT_NEW_DELETED, PERSISTENT_DELETED,
      PERSISTENT_DELETED, PERSISTENT_DELETED, ERROR,
      ERROR, UNCHANGED, UNCHANGED,
      PERSISTENT_DELETED, PERSISTENT_DELETED, ERROR,
      ERROR
    },

    // makeTransactional
    {
      TRANSIENT_CLEAN, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      PERSISTENT_CLEAN, PERSISTENT_DIRTY, ERROR,
      ERROR
    },

    // makeNontransactional
    {
      ERROR, ERROR, PERSISTENT_NONTRANSACTIONAL,
      ERROR, UNCHANGED, TRANSIENT,
      ERROR, ERROR, ERROR,
      UNCHANGED, UNCHANGED, ERROR,
      ERROR
    },

    // makeTransient
    {
      UNCHANGED, ERROR, TRANSIENT,
      ERROR, TRANSIENT, UNCHANGED,
      UNCHANGED, ERROR, ERROR,
      TRANSIENT, ERROR, ERROR,
      ERROR
    },

    // commit, retainValues = false
    {
      UNCHANGED, HOLLOW, HOLLOW,
      HOLLOW, UNCHANGED, UNCHANGED,
      TRANSIENT_CLEAN, TRANSIENT, TRANSIENT,
      UNCHANGED, HOLLOW, UNCHANGED,
      UNCHANGED
    },

    // commit, retainValues = true
    {
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, PERSISTENT_NONTRANSACTIONAL,
      PERSISTENT_NONTRANSACTIONAL, UNCHANGED, UNCHANGED,
      TRANSIENT_CLEAN, TRANSIENT, TRANSIENT,
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
      UNCHANGED
    },

    //  TRANSIENT,                      PERSISTENT_NEW,                     PERSISTENT_CLEAN,
    //  PERSISTENT_DIRTY,               HOLLOW,                             TRANSIENT_CLEAN,
    //  TRANSIENT_DIRTY,                PERSISTENT_NEW_DELETED,             PERSISTENT_DELETED,
    //  PERSISTENT_NONTRANSACTIONAL,    PERSISTENT_NONTRANSACTIONAL_DIRTY,  DETACHED_CLEAN,
    //  DETACHED_DIRTY

    // rollback, restoreValues = false
    {
      UNCHANGED, TRANSIENT, HOLLOW,
      HOLLOW, UNCHANGED, UNCHANGED,
      TRANSIENT_CLEAN, TRANSIENT, HOLLOW,
      UNCHANGED, HOLLOW, UNCHANGED,
      UNCHANGED
    },

    // rollback, restoreValues = true
    {
      UNCHANGED, TRANSIENT, PERSISTENT_NONTRANSACTIONAL,
      PERSISTENT_NONTRANSACTIONAL, UNCHANGED, UNCHANGED,
      TRANSIENT_CLEAN, TRANSIENT, PERSISTENT_NONTRANSACTIONAL,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // refresh with active datastore transaction
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      PERSISTENT_CLEAN, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
      UNCHANGED
    },

    // refresh with active optimistic transaction
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      PERSISTENT_NONTRANSACTIONAL, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
      UNCHANGED
    },

    // evict
    {
      NOT_APPLICABLE, UNCHANGED, HOLLOW,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      HOLLOW, HOLLOW, UNCHANGED,
      UNCHANGED
    },

    // read field outside transaction
    {
      UNCHANGED, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, IMPOSSIBLE,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // read field with active optimistic transaction
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
      UNCHANGED, UNSPECIFIED, UNSPECIFIED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    //  TRANSIENT,                      PERSISTENT_NEW,                     PERSISTENT_CLEAN,
    //  PERSISTENT_DIRTY,               HOLLOW,                             TRANSIENT_CLEAN,
    //  TRANSIENT_DIRTY,                PERSISTENT_NEW_DELETED,             PERSISTENT_DELETED,
    //  PERSISTENT_NONTRANSACTIONAL,    PERSISTENT_NONTRANSACTIONAL_DIRTY,  DETACHED_CLEAN,
    //  DETACHED_DIRTY

    // read field with active datastore transaction
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
      UNCHANGED, UNSPECIFIED, UNSPECIFIED,
      PERSISTENT_CLEAN, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // write field outside transaction
    {
      UNCHANGED, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, IMPOSSIBLE,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      PERSISTENT_NONTRANSACTIONAL_DIRTY, UNCHANGED, DETACHED_DIRTY,
      UNCHANGED
    },

    // write field with active transaction
    {
      UNCHANGED, UNCHANGED, PERSISTENT_DIRTY,
      UNCHANGED, PERSISTENT_DIRTY, TRANSIENT_DIRTY,
      UNCHANGED, ERROR, ERROR,
      PERSISTENT_DIRTY, UNCHANGED, DETACHED_DIRTY,
      UNCHANGED
    },

    // retrieve outside transaction
    {
      UNCHANGED, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, IMPOSSIBLE,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // retrieve with active transaction
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      PERSISTENT_CLEAN, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // commit, detachAllOnCommit = true
    {
      UNCHANGED, DETACHED_CLEAN, DETACHED_CLEAN,
      DETACHED_CLEAN, DETACHED_CLEAN, UNCHANGED,
      TRANSIENT_CLEAN, TRANSIENT, TRANSIENT,
      DETACHED_CLEAN, DETACHED_CLEAN, UNCHANGED,
      UNCHANGED
    },

    //  TRANSIENT,                      PERSISTENT_NEW,                     PERSISTENT_CLEAN,
    //  PERSISTENT_DIRTY,               HOLLOW,                             TRANSIENT_CLEAN,
    //  TRANSIENT_DIRTY,                PERSISTENT_NEW_DELETED,             PERSISTENT_DELETED,
    //  PERSISTENT_NONTRANSACTIONAL,    PERSISTENT_NONTRANSACTIONAL_DIRTY,  DETACHED_CLEAN,
    //  DETACHED_DIRTY

    // detachCopy outside tx with NontransactionalRead=true
    {
      ERROR, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, ERROR,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // detachCopy outside tx with NontransactionalRead=false
    {
      ERROR, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, ERROR, ERROR,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      ERROR, ERROR, ERROR,
      ERROR
    },

    // detachCopy with active datastore tx
    {
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_CLEAN, PERSISTENT_NEW,
      PERSISTENT_NEW, ERROR, ERROR,
      PERSISTENT_CLEAN, IMPOSSIBLE, UNCHANGED,
      UNCHANGED
    },

    // detachCopy with active optimistic tx
    {
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, PERSISTENT_NEW,
      PERSISTENT_NEW, ERROR, ERROR,
      UNCHANGED, IMPOSSIBLE, UNCHANGED,
      UNCHANGED
    },

    // serialize outside tx
    {
      UNCHANGED, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, UNCHANGED, IMPOSSIBLE,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // serialize with active datastore tx
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      PERSISTENT_CLEAN, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // serialize with active optimistic tx
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },
  };

  private static final int DATASTORE_TX = 0;
  private static final int OPTIMISTIC_TX = 1;
  private static final int NO_TX = 2;

  private static final String[] scenario_string = {
    "datastore transaction", "optimistic transaction", "no transaction"
  };

  private static final boolean[][] applies_to_scenario = {
    //  Datastore   Optimistic      No tx
    {true, true, false}, // makePersistent
    {true, true, false}, // deletePersistent
    {true, true, false}, // makeTransactional
    {true, true, false}, // makeNontransactional
    {true, true, false}, // makeTransient
    {true, true, false}, // commit RetainValues = false
    {true, true, false}, // commit RetainValues = true
    {true, true, false}, // rollback RestoreValues = false
    {true, true, false}, // rollback RestoreValues = true
    {true, false, false}, // refresh with active datastore transaction
    {false, true, false}, // refresh with active optimistic transaction
    {true, true, false}, // evict
    {false, false, true}, // read field outside of a transaction
    {false, true, false}, // read field with active optimistic transaction
    {true, false, false}, // read field with active datastore transaction
    {false, false, true}, // write field or makeDirty outside of a transaction
    {true, true, false}, // write field or makeDirty with active transaction
    {false, true, true}, // retrieve outside of a transaction or with active optimistic transaction
    {true, false, false}, // retrieve with active datastore transaction
    {true, true, false}, // commit, DetachAllOnCommit = true
    {false, false, true}, // detachCopy outside tx with NonTransactionaRead=true
    {false, false, true}, // detachCopy outside tx with NonTransactionaRead=false
    {true, false, false}, // detachCopy with active datastore tx
    {false, true, false}, // detachCopy with active optimistic tx
    {false, false, true}, // serialize outside tx
    {true, false, false}, // serialize with active datastore tx
    {false, true, false} // serialize with active optimistic tx
  };

  /**
   * @see org.apache.jdo.tck.JDO_Test#localSetUp()
   */
  @Override
  protected void localSetUp() {
    pm = getPM();
    addTearDownClass(StateTransitionObj.class);
    generatePersistentInstances();
  }

  public void test() {
    scenario = DATASTORE_TX;
    checkTransitions();

    if (isOptimisticSupported()) {
      scenario = OPTIMISTIC_TX;
      checkTransitions();
    }

    scenario = NO_TX;
    checkTransitions();
    failOnError();
  }

  /** */
  private void generatePersistentInstances() {
    if (doPersistentInstancesExist()) return;
    int i;
    Transaction t = pm.currentTransaction();
    t.begin();
    for (i = 0; i < 50; ++i) {
      StateTransitionObj sto = new StateTransitionObj(i);
      sto.writeField(i);
      pm.makePersistent(sto);
    }
    t.commit();
    if (!doPersistentInstancesExist())
      if (debug) logger.debug("StateTransitions unable to create instances of StateTransitionsObj");
  }

  /** */
  private boolean doPersistentInstancesExist() {
    boolean ret;
    Transaction t = pm.currentTransaction();
    t.begin();
    Extent<StateTransitionObj> e = pm.getExtent(StateTransitionObj.class, false);
    Iterator<StateTransitionObj> iter = e.iterator();
    ret = iter.hasNext();
    t.rollback();
    return ret;
  }

  /**
   * @param transaction the transaction
   */
  public void prepareTransactionAndJDOSettings(Transaction transaction) {
    transaction.setNontransactionalRead(false);
    transaction.setNontransactionalWrite(false);
    if (scenario != NO_TX) {
      if (operation == COMMITNORETAINVALUES) transaction.setRetainValues(false);
      if (operation == COMMITRETAINVALUES) transaction.setRetainValues(true);
      if (operation == ROLLBACKNORESTOREVALUES) transaction.setRestoreValues(false);
      if (operation == ROLLBACKRESTOREVALUES) transaction.setRestoreValues(true);
      if (operation == DETACHALLONCOMMIT) pm.setDetachAllOnCommit(true);
      else pm.setDetachAllOnCommit(false);

      transaction.setOptimistic(scenario == OPTIMISTIC_TX);
      transaction.begin();
      if (!transaction.isActive())
        if (debug) logger.debug("StateTransitions: Transaction should be active, but it is not");
    } else {
      if (operation == READOUTSIDETX
          || operation == RETRIEVEOUTSIDETX
          || operation == DETACHCOPYOUTSIDETXNTRTRU
          || operation == SERIALIZEOUTSIDETX) {
        transaction.setNontransactionalRead(true);
      }
      if (operation == WRITEOUTSIDETX || current_state == PERSISTENT_NONTRANSACTIONAL_DIRTY) {
        transaction.setNontransactionalWrite(true);
      }
    }
  }

  /** */
  void checkTransitions() {
    for (operation = 0; operation < NUM_OPERATIONS; ++operation) {
      // rule out situations that do not apply
      if (!applies_to_scenario[operation][scenario]) continue;
      if ((operation == READOUTSIDETX
              || operation == RETRIEVEOUTSIDETX
              || operation == DETACHCOPYOUTSIDETXNTRTRU
              || operation == SERIALIZEOUTSIDETX)
          && !isNontransactionalReadSupported()) continue;
      if (operation == WRITEOUTSIDETX && !isNontransactionalWriteSupported()) continue;
      if (operation == COMMITRETAINVALUES && !isRetainValuesSupported()) continue;
      if (operation == MAKENONTRANSACTIONAL
          && !(isNontransactionalReadSupported() || isNontransactionalWriteSupported())) continue;
      int NUM_JDO1_STATES = NUM_STATES - 2; // JDO1 is tested so far here.
      for (current_state = 0; current_state < NUM_JDO1_STATES; ++current_state) {
        if (scenario == OPTIMISTIC_TX && current_state == PERSISTENT_CLEAN) continue;
        if ((current_state == TRANSIENT_CLEAN || current_state == TRANSIENT_DIRTY)
            && !isTransientTransactionalSupported())
          continue; // this state is not supported by implementation
        if (current_state == PERSISTENT_NONTRANSACTIONAL
            && !(isNontransactionalReadSupported() || isNontransactionalWriteSupported()))
          continue; // this state is not supported by implementation
        if (current_state == PERSISTENT_NONTRANSACTIONAL_DIRTY
            && !isNontransactionalWriteSupported()) continue;

        expected_state = transitions[operation][current_state];
        if (expected_state == IMPOSSIBLE) continue;
        if (expected_state == NOT_APPLICABLE) continue;
        if (expected_state == UNSPECIFIED) continue;
        if (expected_state == UNCHANGED) expected_state = current_state;
        try {
          transaction = pm.currentTransaction();
          if (transaction.isActive()) {
            if (debug) logger.debug("Transaction is active (but should not be), rolling back");
            transaction.rollback();
          }

          prepareTransactionAndJDOSettings(transaction);

          printSituation();

          StateTransitionObj obj = getInstanceInState(current_state);
          if (obj == null) { // could not get object in state
            if (transaction.isActive()) transaction.rollback();
            continue;
          }

          // Apply operation, catching possible exception
          Exception e = null;
          try {
            applyOperation(operation, obj);
          } catch (Exception excep) {
            if (excep instanceof javax.jdo.JDOUserException) {
              e = excep;
            } else {
              appendMessage(
                  ASSERTION_FAILED
                      + NL
                      + "StateTransitions: "
                      + scenario_string[scenario]
                      + "; current state "
                      + states[current_state]
                      + NL
                      + operations[operation]
                      + "; unexpected exception:"
                      + excep);
              continue;
            }
          }

          // Get new state, verify correct transition and exceptions occurred
          new_state = currentState(obj);
          if (expected_state == ERROR) {
            if (e == null) {
              appendMessage(
                  ASSERTION_FAILED
                      + NL
                      + "StateTransitions: "
                      + scenario_string[scenario]
                      + "; current state "
                      + states[current_state]
                      + NL
                      + operations[operation]
                      + "; JDOUserException should have been thrown");
            } else {
              if (!compareStates(new_state, current_state)) {
                appendMessage(
                    ASSERTION_FAILED
                        + NL
                        + "StateTransitions: "
                        + scenario_string[scenario]
                        + "; current state "
                        + states[current_state]
                        + NL
                        + operations[operation]
                        + "; JDOUserException properly thrown, but instance should remain in current state,"
                        + "instance changed state to "
                        + states[new_state]);
              }
            }
          }
          if (!compareStates(new_state, expected_state)) {
            appendMessage(
                ASSERTION_FAILED
                    + NL
                    + "StateTransitions: "
                    + scenario_string[scenario]
                    + "; current state "
                    + states[current_state]
                    + NL
                    + operations[operation]
                    + " transitioned instance to invalid state "
                    + states[new_state]
                    + "; expected state "
                    + states[expected_state]);
          }
          if (transaction.isActive()) transaction.rollback();
        } catch (Exception unexpected_exception) {
          if (debug) {
            unexpected_exception.printStackTrace();
          }
          if (transaction.isActive()) transaction.rollback();
          appendMessage(
              ASSERTION_FAILED
                  + NL
                  + "StateTransitions: "
                  + scenario_string[scenario]
                  + "; current state "
                  + states[current_state]
                  + NL
                  + operations[operation]
                  + "; unexpected exception caught: "
                  + unexpected_exception);
        }
      }
    }
  }

  /** */
  void printSituation() {
    if (debug) {
      logger.debug(
          " ("
              + scenario_string[scenario]
              + ", initial state="
              + states[current_state]
              + ", operation="
              + operations[operation]
              + ")");
    }
  }

  /** */
  @SuppressWarnings("ThrowFromFinallyBlock")
  void applyOperation(int operation, StateTransitionObj stobj) {
    StateTransitionObj obj = stobj;
    switch (operation) {
      case MAKEPERSISTENT:
        {
          pm.makePersistent(obj);
          break;
        }
      case DELETEPERSISTENT:
        {
          pm.deletePersistent(obj);
          break;
        }
      case MAKETRANSACTIONAL:
        {
          pm.makeTransactional(obj);
          break;
        }
      case MAKENONTRANSACTIONAL:
        {
          pm.makeNontransactional(obj);
          break;
        }
      case MAKETRANSIENT:
        {
          pm.makeTransient(obj);
          break;
        }
      case COMMITNORETAINVALUES:
      case COMMITRETAINVALUES:
      case DETACHALLONCOMMIT:
        {
          pm.currentTransaction().commit();
          break;
        }
      case ROLLBACKNORESTOREVALUES:
      case ROLLBACKRESTOREVALUES:
        {
          pm.currentTransaction().rollback();
          break;
        }
      case REFRESHDATASTORE:
      case REFRESHOPTIMISTIC:
        {
          pm.refresh(obj);
          break;
        }
      case EVICT:
        {
          pm.evict(obj);
          break;
        }
      case READOUTSIDETX:
      case READOPTIMISTIC:
      case READDATASTORE:
        {
          obj.readField();
          break;
        }
      case WRITEOUTSIDETX:
      case WRITEINSIDETX:
        {
          obj.writeField(42);
          break;
        }
      case RETRIEVEOUTSIDETX:
      case RETRIEVEINSIDETX:
        {
          pm.retrieve(obj);
          break;
        }
      case DETACHCOPYOUTSIDETXNTRTRU:
      case DETACHCOPYOUTSIDETXNTRFLS:
      case DETACHCOPYINSIDEDATASTORETX:
      case DETACHCOPYINSIDEOPTIMISTICTX:
        {
          pm.detachCopy(obj);
          break;
        }
      case SERIALIZEOUTSIDETX:
      case SERIALIZEDATASTORE:
      case SERIALIZEOPTIMISTIC:
        {
          ObjectOutputStream oos = null;
          try {
            oos = new ObjectOutputStream(new ByteArrayOutputStream());
            oos.writeObject(obj);
          } catch (IOException e) {
            throw new JDOFatalException(e.getMessage(), e);
          } finally {
            if (oos != null) {
              try {
                oos.close();
              } catch (IOException e) {
                throw new JDOFatalException(e.getMessage(), e);
              }
            }
          }
          break;
        }
      default:
        {
          appendMessage(
              ASSERTION_FAILED
                  + NL
                  + "StateTransitions: "
                  + scenario_string[scenario]
                  + "; internal error, illegal operation: "
                  + operation);
        }
    }
  }

  /**
   * Get an instance in the specified state.
   *
   * @param state the state
   * @return instance in the specified state.
   */
  public StateTransitionObj getInstanceInState(int state) {
    switch (state) {
      case TRANSIENT:
        return getTransientInstance();
      case PERSISTENT_NEW:
        return getPersistentNewInstance();
      case PERSISTENT_CLEAN:
        return getPersistentCleanInstance();
      case PERSISTENT_DIRTY:
        return getPersistentDirtyInstance();
      case HOLLOW:
        return getHollowInstance();
      case TRANSIENT_CLEAN:
        return getTransientCleanInstance();
      case TRANSIENT_DIRTY:
        return getTransientDirtyInstance();
      case PERSISTENT_NEW_DELETED:
        return getPersistentNewDeletedInstance();
      case PERSISTENT_DELETED:
        return getPersistentDeletedInstance();
      case PERSISTENT_NONTRANSACTIONAL:
        return getPersistentNontransactionalInstance();
      case PERSISTENT_NONTRANSACTIONAL_DIRTY:
        return getPersistentNontransactionalDirtyInstance();
      case DETACHED_CLEAN:
        return getDetachedCleanInstance();
      case DETACHED_DIRTY:
        return getDetachedDirtyInstance();
      default:
        return null;
    }
  }

  /**
   * @return transient instance
   */
  public StateTransitionObj getTransientInstance() {
    StateTransitionObj obj = new StateTransitionObj(23);
    int curr = currentState(obj);
    if (curr != TRANSIENT) {
      if (debug) {
        logger.debug(
            "StateTransitions: Unable to create transient instance, state is " + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persistent new instance
   */
  public StateTransitionObj getPersistentNewInstance() {
    StateTransitionObj obj = getTransientInstance();
    if (obj == null) return null;
    pm.makePersistent(obj); // should transition to persistent-new
    int curr = currentState(obj);
    if (curr != PERSISTENT_NEW) {
      if (debug) {
        logger.debug(
            "StateTransitions: Unable to create persistent-new instance"
                + " from transient instance via makePersistent(), state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persistent clean instance
   */
  public StateTransitionObj getPersistentCleanInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    StateTransitionObj sto = obj;
    sto.readField();
    int curr = currentState(sto);
    if (curr != PERSISTENT_CLEAN) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-clean instance"
                + " from a hollow instance by reading a field, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persistent dirty instance
   */
  public StateTransitionObj getPersistentDirtyInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    StateTransitionObj pcobj = obj;
    pcobj.writeField(23);
    int curr = currentState(obj);
    if (curr != PERSISTENT_DIRTY) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-dirty instance"
                + " from a hollow instance by writing a field, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return hollow instance
   */
  public StateTransitionObj getHollowInstance() {
    if (!transaction.isActive()) transaction.begin();
    if (!transaction.isActive())
      if (debug) logger.debug("getHollowInstance: Transaction should be active, but it is not");

    Extent<StateTransitionObj> extent = pm.getExtent(StateTransitionObj.class, false);
    Iterator<StateTransitionObj> iter = extent.iterator();
    if (!iter.hasNext()) {
      if (debug) logger.debug("Extent for StateTransitionObj should not be empty");
      return null;
    }
    StateTransitionObj obj = iter.next();

    pm.makeTransactional(obj);
    transaction.setRetainValues(false);
    transaction.commit(); // This should put the instance in the HOLLOW state

    prepareTransactionAndJDOSettings(transaction);

    int curr = currentState(obj);
    if (curr != HOLLOW && curr != PERSISTENT_NONTRANSACTIONAL) {
      if (debug) {
        logger.debug(
            "getHollowInstance: Attempt to get hollow instance via accessing extent failed, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return transient clean instance
   */
  public StateTransitionObj getTransientCleanInstance() {
    StateTransitionObj obj = getTransientInstance();
    if (obj == null) return null;
    pm.makeTransactional(obj);
    int curr = currentState(obj);
    if (curr != TRANSIENT_CLEAN) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create transient-clean instance"
                + " from a transient instance via makeTransactional(), state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return transient dirty instance
   */
  public StateTransitionObj getTransientDirtyInstance() {
    StateTransitionObj obj = getTransientCleanInstance();
    if (obj == null) return null;
    StateTransitionObj pcobj = obj;
    pcobj.writeField(23);
    int curr = currentState(obj);
    if (curr != TRANSIENT_DIRTY) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create transient-dirty instance"
                + " from a transient-clean instance via modifying a field, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persitent new deleted instance
   */
  public StateTransitionObj getPersistentNewDeletedInstance() {
    StateTransitionObj obj = getPersistentNewInstance();
    if (obj == null) return null;
    pm.deletePersistent(obj); // should transition to persistent-new-deleted
    int curr = currentState(obj);
    if (curr != PERSISTENT_NEW_DELETED) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-new-deleted instance"
                + " from a persistent-new instance via deletePersistent, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persitent deleted instance
   */
  public StateTransitionObj getPersistentDeletedInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    pm.deletePersistent(obj);
    int curr = currentState(obj);
    if (curr != PERSISTENT_DELETED) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-deleted instance"
                + " from a persistent instance via deletePersistent(), state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persient nontransactional instance
   */
  public StateTransitionObj getPersistentNontransactionalInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    boolean nontransactionalRead = pm.currentTransaction().getNontransactionalRead();
    pm.currentTransaction().setNontransactionalRead(true);
    obj.readField();
    pm.makeNontransactional(obj);
    pm.currentTransaction().setNontransactionalRead(nontransactionalRead);
    int curr = currentState(obj);
    if (curr != PERSISTENT_NONTRANSACTIONAL && curr != HOLLOW) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-nontransactional instance"
                + " from a persistent-clean instance via makeNontransactional(), state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persient nontransactional dirty instance
   */
  public StateTransitionObj getPersistentNontransactionalDirtyInstance() {
    StateTransitionObj obj = getPersistentNontransactionalInstance();
    if (obj == null) return null;
    obj.writeField(10000);
    int curr = currentState(obj);
    if (curr != PERSISTENT_NONTRANSACTIONAL_DIRTY) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-nontransactional-dirty instance"
                + " from a persistent-clean instance via makeNontransactional()/JDOHelper.makeDirty,"
                + " state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return detached clean instance
   */
  public StateTransitionObj getDetachedCleanInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    obj = pm.detachCopy(obj);
    int curr = currentState(obj);
    if (curr != DETACHED_CLEAN) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create detached-clean instance"
                + " from a persistent-clean instance via detachCopy,"
                + " state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return detached dirty instance
   */
  public StateTransitionObj getDetachedDirtyInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    obj = pm.detachCopy(obj);
    obj.writeField(1000);
    int curr = currentState(obj);
    if (curr != DETACHED_DIRTY) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create detached-dirty instance"
                + " from a persistent-clean instance via detachCopy/persistent field modification,"
                + " state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }
}
