/*
 * 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.Map;
import java.util.Set;
import javax.jdo.Extent;
import javax.jdo.JDOException;
import javax.jdo.JDOFatalException;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Transaction;
import junit.framework.AssertionFailedError;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
import org.apache.jdo.tck.util.BatchTestRunner;
import org.apache.jdo.tck.util.ThreadExceptionHandler;

/**
 * <B>Title:</B> Test PM ability to share PC classes but not PC instances <br>
 * <B>Keywords:</B> PM share PC class <br>
 * <B>Assertion IDs:</B> A5.2-1,A5.2-2,A5.2-3 <br>
 * <B>Assertion Description: </B> Several JDO PersistenceManagers might be coresident and might
 * share the same persistence capable classes] (although a JDO instance can be associated with only
 * one PersistenceManager at a time)
 */
public class PMsCanSharePCClassesButNotPCInstances extends JDO_Test {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertions A5.2-1,A5.2-2,A5.2-3 (PMsCanSharePCClassesButNotPCInstances) failed: ";

  /** The number of active threads. Each thread has its own PM. */
  private int threads = 0;

  /** The total number of attempts to insert PC instances */
  private int attempts = 0;

  /** The number of inserters. Each inserter runs in its own thread. */
  private final int inserters = 5;

  /** The number of objects inserted. */
  protected int insertedCount = 0;

  /** The number of objects that is expected to have been inserted. */
  protected int insertedCountExpected = 0;

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

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

  public void testSharedPC() {
    // test shared PC - only one PM should succeed to insert the shared PC
    threads = 0;
    attempts = 0;
    insertedCount = 0;
    insertedCountExpected = 1;
    insertObjects(true);
  }

  public void testNonSharedPC() {
    // test non-shared PCs - each PM should succeed to insert its own non-shared PC
    threads = 0;
    attempts = 0;
    // insertedCount = 0; //Don't reset this value since we have not deleted the inserted object
    // from the shared PC test above
    insertedCountExpected += inserters;
    insertObjects(false);
  }

  protected void insertObjects(boolean sharedPC) {
    Object pc = null;

    ThreadExceptionHandler threadGroup = new ThreadExceptionHandler();
    for (int i = 0; i < inserters; i++) {
      if (sharedPC) { // each thread shares one PC
        if (pc == null) pc = new StateTransitionObj(i);
      } else { // each thread has its own PC
        pc = new StateTransitionObj(i);
      }
      threads++;
      Thread t = new Thread(threadGroup, new Inserter(pmf, pc, sharedPC));
      t.setName("Inserter-" + i);
      t.start();
    }

    Thread.yield();

    while (!attemptsComplete()) {
      try {
        Thread.sleep(100);
      } catch (InterruptedException ex) {
        logger.debug("interrupted while waiting for threads to insert");
      }
    }

    while (threads > 0) {
      try {
        Thread.sleep(100);
      } catch (InterruptedException ex) {
        logger.debug("interrupted while waiting for threads to finish");
      }
    }

    Set<Map.Entry<Thread, Throwable>> exceptions = threadGroup.getAllUncaughtExceptions();
    for (Map.Entry<Thread, Throwable> entry : exceptions) {
      Thread thread = entry.getKey();
      Throwable throwable = entry.getValue();
      String message = "Uncaught exception " + throwable + " in thread " + thread;
      if (throwable instanceof AssertionFailedError) fail(ASSERTION_FAILED, message);
      else throw new JDOFatalException(message, throwable);
    }
  }

  synchronized void signal() {
    threads--;
  }

  protected synchronized void incrAttempts() {
    attempts++;
  }

  protected synchronized boolean attemptsComplete() {
    return attempts == inserters;
  }

  class Inserter implements Runnable {
    private final PersistenceManager pm;
    private final Object pc;
    private final Class<?> instanceClass;
    private final boolean sharedPC;

    Inserter(PersistenceManagerFactory pmf, Object pc, boolean sharedPC) {
      this.pm = pmf.getPersistenceManager();
      this.pc = pc;
      this.instanceClass = pc.getClass();
      this.sharedPC = sharedPC;
    }

    protected synchronized void announce(String msg, Object pc) {
      insertedCount++;
      Object oid = JDOHelper.getObjectId(pc);
      if (debug) logger.debug(msg + this.getClass().getName() + ": " + oid + ", " + pc);
    }

    public void run() {
      Transaction tx = null;
      try {
        if (debug) logger.debug("running");
        tx = pm.currentTransaction();
        tx.begin();
        try {
          pm.makePersistent(pc);
          announce("inserted ", pc);
          tx.commit();
        } catch (JDOException ex) {
          if (!sharedPC) // we expect an exception for all but one of the inserters in the case of a
            // shared PC
            throw ex;
        } finally {
          incrAttempts();
          if (tx != null && tx.isActive()) tx.rollback();
        }

        while (!attemptsComplete()) {
          try {
            Thread.sleep(100);
          } catch (InterruptedException ex) {
            if (debug) logger.debug(" interrupted");
          }
        }

        // Verify that the number of inserted objects matches the expected number
        if (insertedCount != insertedCountExpected) {
          fail(
              ASSERTION_FAILED,
              "Wrong number of objects in extent. Inserted="
                  + insertedCount
                  + " Expected="
                  + insertedCountExpected);
        }

        if (debug) logger.debug("getting Extent");
        int objCount = 0;
        if (debug) logger.debug("getting Extent of " + instanceClass.getName());
        tx.begin();
        Extent<?> e = pm.getExtent(instanceClass, false);
        for (Object instance : e) {
          objCount++;
        }
        tx.commit();

        // Verify that the number of inserted objects matches the number of objects in the extent
        if (insertedCount != objCount) {
          fail(
              ASSERTION_FAILED,
              "Wrong number of objects in extent. Inserted="
                  + insertedCount
                  + " Found="
                  + objCount);
        }
      } finally {
        if (tx != null && tx.isActive()) tx.rollback();
        if (pm != null && !pm.isClosed()) pm.close();
        PMsCanSharePCClassesButNotPCInstances.this.signal();
      }
    }

    public String toString() {
      String rc = "Inserter ";
      if (debug) {
        rc += Thread.currentThread().toString();
      }
      return rc;
    }
  }
}
