/*
 * 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 java.util.Date;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.instancecallbacks.InstanceCallbackClass;

public abstract class TestParts extends JDO_Test {

  /** */
  public TestParts() {}

  /** */
  void checkInstances(
      String assertion,
      String label,
      int intValue,
      String capturedNextObjName,
      int numberOfChildren,
      int sumOfChildrenIntValue) {
    if (InstanceCallbackClass.processedIndex[intValue] != true) {
      fail(assertion, label + "Callback never made on object with intValue = " + intValue);
    }
    if (capturedNextObjName != null
        && InstanceCallbackClass.capturedNextObjName[intValue] == null) {
      fail(
          assertion,
          label
              + "nextObj attribute for object with intValue = "
              + intValue
              + " should not have been null.");
    } else if (capturedNextObjName == null
        && InstanceCallbackClass.capturedNextObjName[intValue] != null) {
      fail(
          assertion,
          label
              + "nextObj attribute for object with intValue = "
              + intValue
              + " should  have been null.");
    } else if (capturedNextObjName != null
        && !InstanceCallbackClass.capturedNextObjName[intValue].equals(capturedNextObjName)) {
      fail(
          assertion,
          label
              + "nextObj.name attribute for object with intValue = "
              + intValue
              + " should  have been \""
              + capturedNextObjName
              + "\".  It was \""
              + InstanceCallbackClass.capturedNextObjName[intValue]
              + "\" instead.");
    }

    if (InstanceCallbackClass.numberOfChildren[intValue] != numberOfChildren) {
      fail(
          assertion,
          label
              + "Number of instances in attribute children for object with intValue = "
              + intValue
              + " should  have been "
              + numberOfChildren
              + ".  It was "
              + InstanceCallbackClass.numberOfChildren[intValue]
              + " instead.");
    }

    if (InstanceCallbackClass.sumOfChildrenIntValue[intValue] != sumOfChildrenIntValue) {
      fail(
          assertion,
          label
              + "Sum of intValue of instances in attribute children for object with intValue = "
              + intValue
              + " should have been "
              + sumOfChildrenIntValue
              + ".  It was "
              + InstanceCallbackClass.sumOfChildrenIntValue[intValue]
              + " instead.");
    }
  }

  /** */
  void checkPMAccess(String assertion, String label, int intValue, boolean transactionActive) {
    if (InstanceCallbackClass.processedIndex[intValue] != true) {
      fail(assertion, label + "Callback never made on object with intValue = " + intValue);
      return;
    }
    // Only  verify isActive() returned true for the object if transactionActive is true
    if (transactionActive && InstanceCallbackClass.transactionActive[intValue] != true) {
      fail(assertion, label + "PersistenceManager.currentTransaction.isAcive() returned false");
    }
  }

  /** The attributes are: label, name, date, intValue, doubleValue, childToDelete, charValue */
  void checkFieldValues(
      String assertion,
      String label,
      int intValue,
      String name,
      Date timeStamp,
      double doubleValue,
      short childToDelete,
      char charValue) {
    if (InstanceCallbackClass.processedIndex[intValue] != true) {
      fail(assertion, label + "Callback never made on object with intValue = " + intValue);
      return;
    }

    if (!InstanceCallbackClass.capturedName[intValue].equals(name)) {
      fail(
          assertion,
          label
              + "name attribute for object with intValue = "
              + intValue
              + " should be \""
              + name
              + "\".  It was \""
              + InstanceCallbackClass.capturedName[intValue]
              + "\" instead.");
    }

    if (!InstanceCallbackClass.capturedTimeStamp[intValue].equals(timeStamp)) {
      fail(
          assertion,
          label
              + "timeStamp attribute for object with intValue = "
              + intValue
              + " should be "
              + timeStamp
              + ".  It was "
              + InstanceCallbackClass.capturedTimeStamp[intValue]
              + " instead.");
    }

    if (InstanceCallbackClass.capturedDoubleValue[intValue] != doubleValue) {
      fail(
          assertion,
          label
              + "doubleValue attribute for object with intValue = "
              + intValue
              + " should be "
              + doubleValue
              + ".  It was "
              + InstanceCallbackClass.capturedDoubleValue[intValue]
              + " instead.");
    }

    if (InstanceCallbackClass.capturedCharValue[intValue] != charValue) {
      fail(
          assertion,
          label
              + "charValue attribute for object with intValue = "
              + intValue
              + " should be "
              + charValue
              + ".  It was "
              + InstanceCallbackClass.capturedCharValue[intValue]
              + " instead.");
    }

    if (InstanceCallbackClass.capturedChildToDelete[intValue] != childToDelete) {
      fail(
          assertion,
          label
              + "childToDelete attribute for object with intValue = "
              + intValue
              + " should be "
              + childToDelete
              + ".  It was "
              + InstanceCallbackClass.capturedChildToDelete[intValue]
              + " instead.");
    }
  }

  /** Touch fields to guarantee that they are loaded into the instance */
  double touchFields(InstanceCallbackClass o) {
    // make a checksum from the fields and return it; this cannot be optimized out...
    double rc = o.doubleValue;
    rc += o.intValue;
    rc += o.charValue;
    rc += o.childToDelete;
    rc += o.name.length();
    rc += o.timeStamp.getTime();
    return rc;
  }
}
