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

import javax.jdo.Transaction;
import org.apache.jdo.tck.api.persistencemanager.PersistenceManagerTest;
import org.apache.jdo.tck.pc.mylib.PCPoint2;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Evicting With RestoreValues False <br>
 * <B>Keywords:</B> cache <br>
 * <B>Assertion ID:</B> A12.6.1-1. <br>
 * <B>Assertion Description: </B> If users wish to automatically <code>evict</code> transactional
 * instances at transaction <code>rollback</code> time, then they should set <code>RestoreValues
 * </code> to <code>false</code>. For each persistent-clean instance that the JDO <code>
 * PersistenceManager</code> evicts, it:
 *
 * <UL>
 *   <LI>calls the <code>jdoPreClear</code> method on each instance, if the class of the instance
 *       implements <code>InstanceCallbacks</code>
 *   <LI>clears persistent fields on each instance (sets the value of the field to its Java default
 *       value)
 *   <LI>changes the state of instances to hollow
 * </UL>
 */
public class EvictingWithRestoreValuesFalse extends PersistenceManagerTest {

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

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

  /** */
  public void test() {
    pm = getPM();
    PCPoint2 pt = getHollowInstance();

    Transaction tx = pm.currentTransaction();
    tx.setRestoreValues(
        false); // This should cause eviction of transactional instances when transaction is later
    // rolled back.

    // Test
    tx.begin();
    makePersistentClean(pt);
    tx.rollback(); // This should evict pt
    verify(pt);
  }

  /** */
  private PCPoint2 getHollowInstance() {
    Transaction tx = pm.currentTransaction();
    tx.begin();
    PCPoint2 pt = new PCPoint2(1, 2);
    pm.makePersistent(pt);
    tx.commit();

    int curr = currentState(pt);
    if (curr != HOLLOW) {
      fail(ASSERTION_FAILED, "Unable to create HOLLOW instance, state is " + states[curr]);
    }
    return pt;
  }

  /**
   * @param pt PCPont2 instance
   */
  private void makePersistentClean(PCPoint2 pt) {
    pm.makeTransactional(pt);
    int curr = currentState(pt);
    if (curr != PERSISTENT_CLEAN) {
      fail(
          ASSERTION_FAILED, "Unable to create PERSISTENT_CLEAN instance, state is " + states[curr]);
    }
  }

  /**
   * @param pt PCPoint2 instance
   */
  private void verify(PCPoint2 pt) {
    // When PersistenceManager evicts instances, it: calls the jdoPreClear method on each instance
    if (!pt.wasClearCalled()) {
      fail(ASSERTION_FAILED, "missing call of jdoPreClear");
    }

    // When PersistenceManager evicts instances, it: changes the state of the instances to hollow
    int curr = currentState(pt);
    if ((curr != HOLLOW) && (curr != PERSISTENT_NONTRANSACTIONAL)) {
      fail(
          ASSERTION_FAILED,
          "Instance should be HOLLOW after tx.rollback(), state is " + states[curr]);
    }

    pm.makeTransient(pt);
    // When PersistenceManager evicts instances, it: clears persistent fields on each instance (sets
    // the value of the field to its Java default value)
    int x = pt.getX();
    Integer y = pt.getY();
    if ((x != 0) || (y != null)) {
      fail(
          ASSERTION_FAILED,
          "persistent fields not cleared, pt.getX()==" + x + " and pt.getY()==" + y);
    }
  }
}
