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

import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.fieldtypes.FieldsOfObject;
import org.apache.jdo.tck.pc.fieldtypes.SimpleClass;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Support of field type Object. <br>
 * <B>Keywords:</B> model <br>
 * <B>Assertion ID:</B> A6.4.3-31. <br>
 * <B>Assertion Description: </B> JDO implementations must support fields of <code>Object</code>
 * class type as First Class Objects. The implementation is permitted, but is not required, to allow
 * any class to be assigned to the field. If an implementation restricts instances to be assigned to
 * the field, a <code>ClassCastException</code> must be thrown at the time of any incorrect
 * assignment.
 */
public class TestFieldsOfObject extends JDO_Test {

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

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

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

    runTest(pm);

    pm.close();
    pm = null;
  }

  /** */
  void runTest(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    int i, n;
    Object firstValue = new SimpleClass(1, "Hello");
    Object secondValue = new SimpleClass(333, "420");
    tx.begin();
    FieldsOfObject pi = new FieldsOfObject();
    pi.identifier = 1;
    pm.makePersistent(pi);
    Object oid = pm.getObjectId(pi);
    n = pi.getLength();
    // Provide initial set of values
    for (i = 0; i < n; ++i) {
      pi.set(i, firstValue);
    }
    tx.commit();
    // cache will be flushed
    pi = null;
    System.gc();

    tx.begin();
    pi = (FieldsOfObject) pm.getObjectById(oid, true);
    checkValues(oid, firstValue);

    // Provide new set of values
    for (i = 0; i < n; ++i) {
      pi.set(i, secondValue);
    }
    tx.commit();
    // cache will be flushed
    pi = null;
    System.gc();

    tx.begin();
    // check new values
    checkValues(oid, secondValue);
    tx.commit();
  }

  /** */
  private void checkValues(Object oid, Object startValue) {
    int i;
    FieldsOfObject pi = (FieldsOfObject) pm.getObjectById(oid, true);
    int n = pi.getLength();
    StringBuilder buffer = new StringBuilder();
    for (i = 0; i < n; ++i) {
      if (!FieldsOfObject.isPersistent[i]) continue;
      Object val = pi.get(i);
      if (val == null) {
        buffer.append("Field ");
        buffer.append(FieldsOfObject.fieldSpecs[i]);
        buffer.append(" is null. Expected ");
        buffer.append(startValue.toString());
        buffer.append(".\n");
        continue;
      }
      if (!val.equals(startValue)) {
        buffer.append("Field ");
        buffer.append(FieldsOfObject.fieldSpecs[i]);
        buffer.append(" has wrong value: expected ");
        buffer.append(startValue.toString());
        buffer.append(" actual ");
        buffer.append(val);
        buffer.append(".\n");
      }
    }
    if (buffer.length() > 0) {
      fail(ASSERTION_FAILED, buffer.toString());
    }
  }
}
