/*
 * 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 javax.jdo.spi;

import java.util.Collection;
import java.util.Properties;
import javax.jdo.Constants;
import javax.jdo.JDOUserException;
import javax.jdo.pc.PCPoint;
import javax.jdo.util.AbstractTest;
import javax.jdo.util.BatchTestRunner;

/**
 * Tests class javax.jdo.spi.JDOImplHelper.
 *
 * <p>Missing: testNewInstance + testNewObjectIdInstance Missing: tests for JDOImplHelper methods:
 * copyKeyFieldsToObjectId and copyKeyFieldsFromObjectId.
 */
public class JDOImplHelperTest extends AbstractTest {

  /** */
  private RegisterClassEvent event;

  /** */
  public static void main(String args[]) {
    BatchTestRunner.run(JDOImplHelperTest.class);
  }

  /** */
  public void setUp() {
    // make sure PCClass is loaded before any tests are run
    new PCPoint(1, Integer.valueOf(1));
  }

  /** */
  public void testGetFieldNames() {
    JDOImplHelper implHelper = JDOImplHelper.getInstance();
    String[] fieldNames = implHelper.getFieldNames(PCPoint.class);
    if (fieldNames == null) {
      fail("array of field names is null");
    }
    if (fieldNames.length != 2) {
      fail("Unexpected length of fieldNames; expected 2, got " + fieldNames.length);
    }
    if (!fieldNames[0].equals("x")) {
      fail("Unexpected field; expected x, got " + fieldNames[0]);
    }
    if (!fieldNames[1].equals("y")) {
      fail("Unexpected field; expected y, got " + fieldNames[1]);
    }
  }

  /** */
  public void testGetFieldTypes() {
    JDOImplHelper implHelper = JDOImplHelper.getInstance();
    Class<?>[] fieldTypes = implHelper.getFieldTypes(PCPoint.class);
    if (fieldTypes == null) {
      fail("array of field types is null");
    }
    if (fieldTypes.length != 2) {
      fail("Unexpected length of fieldTypes; expected 2, got " + fieldTypes.length);
    }
    if (fieldTypes[0] != int.class) {
      fail("Unexpected field type; expected int, got " + fieldTypes[0]);
    }
    if (fieldTypes[1] != Integer.class) {
      fail("Unexpected field type; expected Integer, got " + fieldTypes[1]);
    }
  }

  /** */
  public void testGetFieldFlags() {
    byte expected =
        (byte)
            (PersistenceCapable.CHECK_READ
                + PersistenceCapable.CHECK_WRITE
                + PersistenceCapable.SERIALIZABLE);

    JDOImplHelper implHelper = JDOImplHelper.getInstance();
    byte[] fieldFlags = implHelper.getFieldFlags(PCPoint.class);
    if (fieldFlags == null) {
      fail("array of field flags is null");
    }
    if (fieldFlags.length != 2) {
      fail("Unexpected length of fieldFlags; expected 2, got " + fieldFlags.length);
    }
    if (fieldFlags[0] != expected) {
      fail("Unexpected field flag; expected " + expected + ", got " + fieldFlags[0]);
    }
    if (fieldFlags[1] != expected) {
      fail("Unexpected field flag; expected " + expected + ", got " + fieldFlags[1]);
    }
  }

  /** */
  public void testGetPCSuperclass() {
    JDOImplHelper implHelper = JDOImplHelper.getInstance();
    Class<?> pcSuper = implHelper.getPersistenceCapableSuperclass(PCPoint.class);
    if (pcSuper != null) {
      fail("Wrong pc superclass of PCPoint; expected null, got " + pcSuper);
    }
  }

  /** */
  public void testNewInstance() {
    // TBD: test JDOImplHelper.newInstance(pcClass, sm) and
    // JDOImplHelper.newInstance(pcClass, sm, oid)
  }

  /** */
  public void testNewObjectIdInstance() {
    // TBD: test JDOImplHelper.newObjectIdInstance(pcClass)
  }

  /** */
  public void testClassRegistration() {
    JDOImplHelper implHelper = JDOImplHelper.getInstance();

    Collection<Class<?>> registeredClasses = implHelper.getRegisteredClasses();
    // test whether PCPoint is registered
    if (!registeredClasses.contains(PCPoint.class)) {
      fail("Missing registration of pc class PCPoint");
    }

    // Save registered meta data for restoring
    String[] fieldNames = implHelper.getFieldNames(PCPoint.class);
    Class<?>[] fieldTypes = implHelper.getFieldTypes(PCPoint.class);
    byte[] fieldFlags = implHelper.getFieldFlags(PCPoint.class);
    Class<?> pcSuperclass = implHelper.getPersistenceCapableSuperclass(PCPoint.class);

    // test unregisterClass with null parameter
    try {
      implHelper.unregisterClass(null);
      fail("Missing exception when calling unregisterClass(null)");
    } catch (NullPointerException ex) {
      // expected exception => OK
    }

    // test unregister PCPoint class
    implHelper.unregisterClass(PCPoint.class);
    registeredClasses = implHelper.getRegisteredClasses();
    if (registeredClasses.contains(PCPoint.class)) {
      fail("PCPoint still registered");
    }

    // register PCPoint again
    JDOImplHelper.registerClass(
        PCPoint.class, fieldNames, fieldTypes, fieldFlags, pcSuperclass, new PCPoint());
  }

  /** */
  public void testClassListenerRegistration() {
    JDOImplHelper implHelper = JDOImplHelper.getInstance();

    // add listener and check event
    event = null;
    RegisterClassListener listener = new SimpleListener();
    implHelper.addRegisterClassListener(listener);
    JDOImplHelper.registerClass(
        JDOImplHelperTest.class, new String[0], new Class[0], new byte[0], null, null);
    if (event == null) {
      fail("Missing event ");
    }

    // remove listener and check event
    event = null;
    implHelper.removeRegisterClassListener(listener);
    JDOImplHelper.registerClass(
        JDOImplHelperTest.class, new String[0], new Class[0], new byte[0], null, null);
    if (event != null) {
      fail("Unexpected event " + event);
    }
  }

  /** Test that an unknown standard property causes JDOUserException. */
  public void testUnknownStandardProperty() {
    Properties p = new Properties();
    p.setProperty("javax.jdo.unknown.standard.property", "value");

    JDOUserException x = null;

    try {
      JDOImplHelper.assertOnlyKnownStandardProperties(p);
      fail(
          "testUnknownStandardProperty should result in JDOUserException. "
              + "No exception was thrown.");
    } catch (JDOUserException thrown) {
      if (verbose) println("Caught expected exception " + thrown);
      x = thrown;
    }
    assertNull("should have had no nested exceptions", x.getNestedExceptions());
  }

  /** Test that unknown standard properties cause JDOUserException w/nested exceptions. */
  public void testUnknownStandardProperties() {
    Properties p = new Properties();
    p.setProperty("javax.jdo.unknown.standard.property.1", "value");
    p.setProperty("javax.jdo.unknown.standard.property.2", "value");

    JDOUserException x = null;

    try {
      JDOImplHelper.assertOnlyKnownStandardProperties(p);
      fail(
          "testUnknownStandardProperties should result in JDOUserException. "
              + "No exception was thrown.");
    } catch (JDOUserException thrown) {
      if (verbose) println("Caught expected exception " + thrown);
      x = thrown;
    }

    Throwable[] nesteds = x.getNestedExceptions();

    assertNotNull(nesteds);
    assertEquals("should have been 2 nested exceptions", 2, nesteds.length);
    for (int i = 0; i < nesteds.length; i++) {
      Throwable t = nesteds[i];
      assertTrue(
          "nested exception " + i + " should have been JDOUserException",
          t instanceof JDOUserException);
    }
  }

  /**
   * Test that unknown non-standard properties & well-formed listener properties don't cause
   * JDOUserException.
   */
  public void testUnknownNonStandardPropertiesAndListeners() {
    Properties p = new Properties();
    p.put("unknown.property", "value");
    p.put(new Object(), "value");
    p.put(Constants.PROPERTY_PREFIX_INSTANCE_LIFECYCLE_LISTENER + "unknown.listener", "value");
    JDOImplHelper.assertOnlyKnownStandardProperties(p);
  }

  /** Test that all JDO standard properties don't cause JDOUserException. */
  public void testOnlyStandardProperties() {
    Properties props = new Properties();
    for (String p : JDOImplHelper.USER_CONFIGURABLE_STANDARD_PROPERTIES) {
      props.setProperty(p, p);
    }
    JDOImplHelper.assertOnlyKnownStandardProperties(props);
  }

  /** Test that an known standard property in mixed case succeeds. */
  public void testKnownStandardPropertyThatDiffersInCaseOnly() {
    Properties p = new Properties();
    p.setProperty("JaVaX.jDo.oPtIoN.CoNNectionDRiVerNamE", "value");
    p.setProperty("jAvAx.JdO.lIsTeNeR.InstaNceLifeCycleLisTener.foo.Bar", "");
    JDOImplHelper.assertOnlyKnownStandardProperties(p);
  }

  /** */
  class SimpleListener implements RegisterClassListener {

    /** */
    public void registerClass(RegisterClassEvent event) {
      JDOImplHelperTest.this.event = event;
    }
  }
}
