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

import javax.jdo.JDODataStoreException;
import javax.jdo.JDOUserException;
import javax.jdo.Transaction;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.instancecallbacks.InstanceCallbackNonPersistFdsClass;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Modification of Nontransactional Nonpersistent Fields <br>
 * <B>Keywords:</B> instancecallbacks <br>
 * <B>Assertion ID:</B> A6.4.1-3. <br>
 * <B>Assertion Description: </B> Nontransactional non-persistent fields may be modified during
 * execution of user-written callbacks defined in interface <code>InstanceCallbacks</code> at
 * specific points in the life cycle.
 */

/*
 *  Test jdoPostLoad() by setting values into the non-managed and transactional attriubes.
 *    This includes creating and populating a collection and initializing a Date.
 *  Verify those values are set once the object is referenced.
 *
 *  Test jdoPreClear(), jdoPreDelete() & jdoPreStore() by setting values into the nonmanaged and transactional attributes.
 *   This includes setting a collection and Date to null.
 *  Verify that no exceptions are thrown.
 */
public class ModificationOfNontransactionalNonpersistentFields extends JDO_Test {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertion A6.4.1-3 (ModificationOfNontransactionalNonpersistentFields) 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(ModificationOfNontransactionalNonpersistentFields.class);
  }

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

  /** */
  public void test() {
    pm = getPM();
    Transaction t = pm.currentTransaction();
    t.setRetainValues(false);

    InstanceCallbackNonPersistFdsClass.initializeStaticsForTest();

    t.begin();
    // create instance
    InstanceCallbackNonPersistFdsClass obj1 = new InstanceCallbackNonPersistFdsClass(1.1f, 1);
    pm.makePersistent(obj1);
    Object objPtr1 = pm.getObjectId(obj1);
    obj1.setNonPersist(1, (char) 1, 0, (short) 0);
    t.commit(); // jdoPreStore() and jdoPreClear() called

    t.begin();
    try {
      obj1 =
          (InstanceCallbackNonPersistFdsClass)
              pm.getObjectById(objPtr1, true); // jdoPostLoad() called
    } catch (JDOUserException | JDODataStoreException e) {
      // could not locate persistent object created in previous transaction
      fail(
          ASSERTION_FAILED,
          "ModificationOfNontransactionalNonpersistentFields:  Could not locate persistent object obj1 created in previous transaction, got "
              + e);
      return;
    }

    // check fields set in jdoPostLoad()
    if (obj1.i != -10) {
      fail(ASSERTION_FAILED, "jdoPostLoad:  Value incorrect, obj1.i != -10; it is " + obj1.i);
    }
    if (obj1.c != '2') {
      fail(ASSERTION_FAILED, "jdoPostLoad:  Value incorrect, obj1.c != '2'; it is " + obj1.c);
    }
    if (obj1.d != 30.0) {
      fail(ASSERTION_FAILED, "jdoPostLoad:  Value incorrect, obj1.d != 30.0; it is " + obj1.d);
    }
    if (obj1.s != 40) {
      fail(ASSERTION_FAILED, "jdoPostLoad:  Value incorrect, obj1.s != 40; it is " + obj1.s);
    }
    if (obj1.loadTime != InstanceCallbackNonPersistFdsClass.savedLoadTime) {
      fail(
          ASSERTION_FAILED,
          "jdoPostLoad:  Value incorrect, obj1.loadTime != "
              + InstanceCallbackNonPersistFdsClass.savedLoadTime
              + "; it is "
              + obj1.loadTime);
    }
    boolean childrenValueIncorrect = false;
    if (obj1.children.size() != 3) {
      childrenValueIncorrect = true;
    } else {
      if (!obj1.children.contains(InstanceCallbackNonPersistFdsClass.member1)) {
        childrenValueIncorrect = true;
      }
      if (!obj1.children.contains(InstanceCallbackNonPersistFdsClass.member2)) {
        childrenValueIncorrect = true;
      }
      if (!obj1.children.contains(InstanceCallbackNonPersistFdsClass.member3)) {
        childrenValueIncorrect = true;
      }
    }
    if (childrenValueIncorrect) {
      if (debug) {
        logger.debug(
            "jdoPostLoad:  Value incorrect, obj1.children does not contain the correct String members");
        logger.debug(
            "The members should be: "
                + InstanceCallbackNonPersistFdsClass.member1
                + ", "
                + InstanceCallbackNonPersistFdsClass.member2
                + ", "
                + InstanceCallbackNonPersistFdsClass.member3);
        logger.debug("obj1.children contains " + obj1.children.size() + " members");
        if (obj1.children.size() != 0) {
          logger.debug("Those members are:");
          for (String s : obj1.children) {
            logger.debug(s);
          }
        }
      }
      fail(
          ASSERTION_FAILED,
          "jdoPostLoad:  Value incorrect, obj1.children does not contain the correct String members");
    }

    pm.deletePersistent(obj1); // jdoPreDelete() called
    t.commit();
    // check result of jdoPreStore(), jdoPreClear() and jdoPreDelete()
    if (!InstanceCallbackNonPersistFdsClass.preClearCalled) {
      fail(ASSERTION_FAILED, "jdoPreClear() never called on obj1");
    }

    if (!InstanceCallbackNonPersistFdsClass.preStoreCalled) {
      fail(ASSERTION_FAILED, "jdoPreStore() never called on obj1");
    }

    if (!InstanceCallbackNonPersistFdsClass.preDeleteCalled) {
      fail(ASSERTION_FAILED, "jdoPreDelete() never called on obj1");
    }

    if (InstanceCallbackNonPersistFdsClass.exceptions.size() != 0) {
      for (int index = 0; index < InstanceCallbackNonPersistFdsClass.exceptions.size(); index++) {
        fail(
            ASSERTION_FAILED,
            ""
                + InstanceCallbackNonPersistFdsClass.callbackCalled.get(index)
                + "operation "
                + InstanceCallbackNonPersistFdsClass.attributeOpCausingExceptions.get(index)
                + " resulted in exception "
                + InstanceCallbackNonPersistFdsClass.exceptions.get(index));
      }
    }
    pm.close();
    pm = null;
  }
}
