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

import java.util.Iterator;
import javax.jdo.Extent;
import javax.jdo.PersistenceManager;
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 that Multiple PMs return different instances representing same PC object <br>
 * <B>Keywords:</B> lifecycle Multiple PMs getObjectById equal <br>
 * <B>Assertion IDs:</B> A5.4-7 <br>
 * <B>Assertion Description: </B> The instance returned by a call to getObjectById(Object) of
 * different PersistenceManager instances returned by the same PersistenceManagerFactory represent
 * the same persistent object, but with different Java object identity (specifically, all instances
 * returned by getObjectId from the instances must return true to equals comparisons with all
 * others).
 */
public class MultiplePMsReturnInstancesRepresentingSamePC extends JDO_Test {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertion A5.4-7 (MultiplePMsReturnInstancesRepresentingSamePC) failed: ";

  private static final int NUM_OBJECTS = 50;

  /** The persistent instances of this test. */
  private Object[] obj;

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

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

  public void test() {
    PersistenceManager pm2 = null;
    PersistenceManager pm3 = null;

    try {
      // Get two more PMs
      pm2 = pmf.getPersistenceManager();
      pm3 = pmf.getPersistenceManager();

      pm.currentTransaction().begin();

      Extent<StateTransitionObj> extent = pm.getExtent(StateTransitionObj.class, false);
      Iterator<StateTransitionObj> iter = extent.iterator();
      if (!iter.hasNext()) {
        fail(ASSERTION_FAILED, "Extent for StateTransitionObj should not be empty");
      }
      extent.close(iter);

      for (int i = 0; i < NUM_OBJECTS; i++) {
        Object obj1 = obj[i];
        Object objId1 = pm.getObjectId(obj1);
        Object obj2 = pm2.getObjectById(objId1, false);
        Object objId2 = pm2.getObjectId(obj2);
        Object obj3 = pm3.getObjectById(objId1, false);
        Object objId3 = pm3.getObjectId(obj3);

        // Verify that objects are different instances
        if (!((obj1 != obj2) && (obj1 != obj3))) {
          fail(
              ASSERTION_FAILED,
              "Objects are not different instances. obj1="
                  + obj1
                  + " obj2= "
                  + obj2
                  + " obj3= "
                  + obj3);
        }

        // Verify that object Ids are equal
        if (!(objId1.equals(objId2) && objId1.equals(objId3))) {
          fail(
              ASSERTION_FAILED,
              "Object Ids are not equal. objId1="
                  + objId1
                  + " objId2= "
                  + objId2
                  + " objId3= "
                  + objId3);
        }
      }

      pm.currentTransaction().commit();
    } finally {
      if (pm != null && pm.currentTransaction().isActive()) {
        pm.currentTransaction().rollback();
      }
      if (pm2 != null && !pm2.isClosed()) {
        pm2.close();
      }
      if (pm3 != null && !pm3.isClosed()) {
        pm3.close();
      }
    }
  }

  private Object[] generatePersistentInstances() {
    StateTransitionObj[] objects = new StateTransitionObj[NUM_OBJECTS];
    try {
      Transaction t = pm.currentTransaction();
      t.begin();
      for (int i = 0; i < NUM_OBJECTS; ++i) {
        objects[i] = new StateTransitionObj(i);
        objects[i].writeField(i);
        pm.makePersistent(objects[i]);
      }
      t.commit();
      return objects;
    } finally {
      Transaction tx = pm.currentTransaction();
      if (tx.isActive()) {
        tx.rollback();
      }
    }
  }
}
