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