/*
 * 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.api.persistencemanager.cache;

import javax.jdo.JDOFatalException;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Transaction;
import junit.framework.AssertionFailedError;
import org.apache.jdo.tck.api.persistencemanager.PersistenceManagerTest;
import org.apache.jdo.tck.pc.mylib.PCPoint;
import org.apache.jdo.tck.util.BatchTestRunner;
import org.apache.jdo.tck.util.ThreadExceptionHandler;

/**
 * <B>Title:</B> Refresh Side Effects <br>
 * <B>Keywords:</B> cache <br>
 * <B>Assertion ID:</B> A12.5.1-5A <br>
 * <B>Assertion Description: </B> The refresh method updates the values in the parameter instance[s]
 * from the data in the data store. ((The intended use is for optimistic transactions where the
 * state of the JDO Instance is not guaranteed to reflect the state in the data store. This method
 * can be used to minimize the occurrence of commit failures due to mismatch between the state of
 * cached instances and the state of data in the data store.)) This can be tested by using 2
 * PersistenceManagers, independently change an object, then refresh.
 */
public class RefreshSideEffects extends PersistenceManagerTest {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertion A12.5.1-5A (RefreshSideEffects) failed: ";

  /** */
  static final int DELAY = 100;

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

  /**
   * @throws Exception exception
   */
  public void test() throws Exception {
    PersistenceManagerFactory pmf = getPMF();
    PersistenceManager pm1 = pmf.getPersistenceManager();
    PersistenceManager pm2 = pmf.getPersistenceManager();

    try {
      runTestRefreshSideEffects(pm1, pm2);
    } finally {
      cleanupPM(pm2);
      pm2 = null;
      cleanupPM(pm1);
      pm1 = null;
    }
  }

  /**
   * @param pm1 the first PersistenceManager
   * @param pm2 the second PersistenceManager
   * @throws Exception
   */
  private void runTestRefreshSideEffects(PersistenceManager pm1, PersistenceManager pm2)
      throws Exception {
    if (debug) logger.debug("\nSTART RefreshSideEffects");

    ThreadExceptionHandler group = new ThreadExceptionHandler();
    RefreshThreadT1 thread1 = new RefreshThreadT1(pm1);
    Thread T1 = new Thread(group, thread1, "T1");
    RefreshThreadT2 thread2 = new RefreshThreadT2(pm2);
    Thread T2 = new Thread(group, thread2, "T2");
    thread1.setOther(thread2);
    thread2.setOther(thread1);

    T1.start();
    T2.start();

    T1.join();
    T2.join();

    Throwable t1Problem = group.getUncaughtException(T1);
    if (t1Problem != null) {
      if (t1Problem instanceof AssertionFailedError) throw (AssertionFailedError) t1Problem;
      else
        throw new JDOFatalException("Thread " + T1.getName() + " results in exception ", t1Problem);
    }
    Throwable t2Problem = group.getUncaughtException(T2);
    if (t2Problem != null) {
      if (t2Problem instanceof AssertionFailedError) throw (AssertionFailedError) t2Problem;
      else
        throw new JDOFatalException("Thread " + T2.getName() + " results in exception ", t2Problem);
    }

    if (debug) logger.debug("END RefreshSideEffects");
  }

  /** */
  class RefreshThreadT1 implements Runnable {

    private final PersistenceManager pm;
    private RefreshThreadT2 other;
    private boolean commitDone;

    /** */
    RefreshThreadT1(PersistenceManager pm) {
      this.pm = pm;
      this.other = null;
      this.commitDone = false;
    }

    /** */
    void setOther(RefreshThreadT2 other) {
      this.other = other;
    }

    /** */
    boolean isCommitDone() {
      return commitDone;
    }

    /** */
    public synchronized void run() {
      PCPoint n1 = new PCPoint(5, 1);
      Transaction tx = pm.currentTransaction();
      try {
        RefreshSideEffects.this.logger.debug("  ThreadT1: START");
        tx.begin();
        n1.setX(500);
        pm.makePersistent(n1);
        pm.refresh(n1);

        RefreshSideEffects.this.logger.debug("  ThreadT1: waiting for ThreadT2.done");
        while (!other.isDone()) {
          try {
            Thread.sleep(DELAY);
          } catch (InterruptedException ex) {
            // ignore
          }
        }

        tx.commit();
        tx = null;
        commitDone = true;
        RefreshSideEffects.this.logger.debug("  ThreadT1: commit finished.");
      } finally {
        commitDone = true;
        if ((tx != null) && tx.isActive()) tx.rollback();
      }
    }
  }

  /** */
  class RefreshThreadT2 implements Runnable {

    private final PersistenceManager pm;
    private RefreshThreadT1 other;
    private boolean done;

    /** */
    RefreshThreadT2(PersistenceManager pm) {
      this.pm = pm;
      this.other = null;
      this.done = false;
    }

    /** */
    boolean isDone() {
      return done;
    }

    /** */
    void setOther(RefreshThreadT1 other) {
      this.other = other;
    }

    /* test refresh() */
    public synchronized void run() {
      PCPoint p1 = new PCPoint(5, 1);
      Transaction tx = pm.currentTransaction();
      try {
        RefreshSideEffects.this.logger.debug("  ThreadT2: START");
        tx.begin();
        p1.setX(201);
        pm.makePersistent(p1);
        pm.refresh(p1);
        done = true;

        RefreshSideEffects.this.logger.debug("  ThreadT2: waiting for commit of ThreadT1");
        while (!other.isCommitDone()) {
          try {
            Thread.sleep(DELAY);
          } catch (InterruptedException ex) {
            // ignore
          }
        }
        tx.commit();
        tx = null;
        RefreshSideEffects.this.logger.debug("  ThreadT2: commit finished.");
      } finally {
        done = true;
        if ((tx != null) && tx.isActive()) tx.rollback();
      }
    }
  }
}
