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

import java.util.Collection;
import java.util.HashSet;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import org.apache.jdo.tck.api.persistencemanager.PersistenceManagerTest;
import org.apache.jdo.tck.pc.mylib.PCPoint;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Make Nontransactional a Persistent-Clean Instance <br>
 * <B>Keywords:</B> lifecycle <br>
 * <B>Assertion IDs:</B> A12.5.7-27 <br>
 * <B>Assertion Description: </B> PersistenceManager.makeNontransactional and
 * makeNontransactionalAll makes a persistent-clean instance nontransactional and causes a state
 * transition to persistent-nontransactional.
 */
public class MakeNontransactionalPersistentCleanInstance extends PersistenceManagerTest {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertion A12.5.7-27 (MakeNontransactionalPersistentCleanInstance) 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(MakeNontransactionalPersistentCleanInstance.class);
  }

  private PCPoint p1 = null;
  private PCPoint p2 = null;
  private PCPoint p3 = null;
  private PCPoint p4 = null;
  private PCPoint p5 = null;
  private PCPoint p6 = null;
  private PCPoint p7 = null;

  private final Collection<PCPoint> col1 = new HashSet<>();
  private final Collection<PCPoint> col2 = new HashSet<>();

  /** */
  public void testTransactionalInstance() {
    pm = getPM();

    createObjects(pm);
    runTestMakeNontransactionalPersistentCleanInstance(pm);
    runTestMakeNontransactionalPersistentCleanInstanceAll1(pm);
    runTestMakeNontransactionalPersistentCleanInstanceAll2(pm);

    pm.close();
    pm = null;
  }

  /** */
  private void createObjects(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    try {
      tx.setOptimistic(false);
      tx.begin();
      p1 = new PCPoint(1, 3);
      p2 = new PCPoint(2, 4);
      p3 = new PCPoint(3, 5);
      p4 = new PCPoint(4, 6);
      p5 = new PCPoint(5, 7);
      p6 = new PCPoint(6, 8);
      p7 = new PCPoint(7, 9);

      col1.add(p2);
      col1.add(p3);
      col1.add(p4);

      col2.add(p5);
      col2.add(p6);
      col2.add(p7);

      pm.makePersistent(p1);
      pm.makePersistent(p2);
      pm.makePersistent(p3);
      pm.makePersistent(p4);
      pm.makePersistent(p5);
      pm.makePersistent(p6);
      pm.makePersistent(p7);
      tx.commit();
      tx = null;
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void runTestMakeNontransactionalPersistentCleanInstance(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    try {
      if (debug) logger.debug(" ** in testMakeNontransactionalPersistentCleanInstance()");
      int curr;
      tx.setOptimistic(false);
      tx.begin();

      if (makePersistentCleanInstance(p1)) {
        pm.makeNontransactional(p1);
        curr = currentState(p1);

        if (curr == HOLLOW || curr == PERSISTENT_NONTRANSACTIONAL) {
        } else {
          fail(
              ASSERTION_FAILED,
              "Excpected P-HOLLOW or P-NONTX instance, instance is " + getStateOfInstance(p1));
        }
      }
      tx.commit();
      tx = null;
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void runTestMakeNontransactionalPersistentCleanInstanceAll1(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    try {
      if (debug) logger.debug(" ** in testMakeNontransactionalPersistentCleanInstanceAll1()");
      int curr;

      tx.setOptimistic(false);
      tx.begin();

      if (makePersistentCleanInstance(p2)
          && makePersistentCleanInstance(p3)
          && makePersistentCleanInstance(p4)) {

        pm.makeNontransactionalAll(col1);
        for (PCPoint p : col1) {
          curr = currentState(p);
          if (curr == HOLLOW || curr == PERSISTENT_NONTRANSACTIONAL) {
          } else {
            fail(
                ASSERTION_FAILED,
                "Expected persistent-nontransactional or hollow; got " + getStateOfInstance(p));
          }
        }
      }
      tx.commit();
      tx = null;
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void runTestMakeNontransactionalPersistentCleanInstanceAll2(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    try {
      if (debug) logger.debug(" ** in testMakeNontransactionalPersistentCleanInstanceAll2()");
      int curr;
      if (tx.getOptimistic()) if (debug) logger.debug(" opt flag set to true");
      tx.begin();

      Object[] objArray = col2.toArray();

      if (makePersistentCleanInstance(p5)
          && makePersistentCleanInstance(p6)
          && makePersistentCleanInstance(p7)) {

        pm.makeNontransactionalAll(objArray);

        for (Object o : objArray) {
          PCPoint p = (PCPoint) o;
          curr = currentState(p);
          if (curr == HOLLOW || curr == PERSISTENT_NONTRANSACTIONAL) {
          } else {
            fail(
                ASSERTION_FAILED,
                "Expected persistent-nontransactional or hollow; got " + getStateOfInstance(p));
          }
        }
      }
      tx.commit();
      tx = null;
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private boolean makePersistentCleanInstance(PCPoint obj) {
    int val = obj.getX();
    return (testState(obj, PERSISTENT_CLEAN, "persistent clean"));
  }
}
