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

import java.lang.reflect.InvocationTargetException;
import java.security.PrivilegedAction;
import javax.jdo.JDOFatalInternalException;
import javax.jdo.JDOFatalUserException;
import javax.jdo.JDOUserException;
import javax.jdo.LegacyJava;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B>Close of PersistenceManagerFactory <br>
 * <B>Keywords:</B> persistencemanagerfactory <br>
 * <B>Assertion IDs:</B> A11.4-2, A11.4-10 <br>
 * <B>Assertion Description: </B> PersistenceManagerFactory.close() closes this
 * PersistenceManagerFactory. <B>Assertion Description: </B> PersistenceManagerFactory.isClosed();
 * Return true if this PersistenceManagerFactory is closed; and false otherwise.
 */
public class Close extends JDO_Test {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertions A11.4-2 (Close), A11.4-10 (isClosed) 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(Close.class);
  }

  @SuppressWarnings("unchecked")
  private static <T> T doPrivileged(PrivilegedAction<T> privilegedAction) {
    try {
      return (T) LegacyJava.doPrivilegedAction.invoke(null, privilegedAction);
    } catch (IllegalAccessException | InvocationTargetException e) {
      if (e.getCause() instanceof RuntimeException) {
        throw (RuntimeException) e.getCause();
      }
      throw new JDOFatalInternalException(e.getMessage());
    }
  }

  /** */
  public void test() {
    pmf = getPMF();

    // check pmf.isClosed() before and after pmf.close()
    try {
      if (pmf.isClosed()) {
        fail(ASSERTION_FAILED, "PMF.isClosed() returned true on an open pmf");
      }

      closePMF(pmf); // don't use closePMF() because that sets pmf to null

      if (!pmf.isClosed()) {
        fail(ASSERTION_FAILED, "PMF.isClosed() returned false on a closed pmf");
      }
    } catch (JDOUserException | JDOFatalUserException ex) {
      // unexpected exception
      fail(ASSERTION_FAILED, "Unexpected exception at pmf.close()/isClosed(): " + ex);
    }

    // pmf.close() on already-closed pmf should not throw an exception
    try {
      // don't use closePMF methods because they check isClosed before calling
      doPrivileged(
          () -> {
            pmf.close();
            return null;
          });
    } catch (JDOUserException | JDOFatalUserException ex) {
      // unexpected exception
      fail(ASSERTION_FAILED, "Unexpected exception at repeated pmf.close(): " + ex);
    }

    // trying to get a getPersistenceManager should result in a exception
    try {
      pm = pmf.getPersistenceManager();
      fail(
          ASSERTION_FAILED,
          "JDOUserException was not thrown when calling pmf.getPersistenceManager() after pmf was closed");
    } catch (JDOUserException ex) {
      // expected exception
      if (debug) {
        logger.debug("caught expected exception " + ex);
      }
    } catch (JDOFatalUserException ex) {
      // unexpected exception
      fail(
          ASSERTION_FAILED,
          "Wrong exception thrown from getPersistenceManager after close.\n"
              + "Expected JDOUserException, got JDOFatalUserException.");
    }

    // have next invocation of getPMF() get a new pmf
    pmf = null;
  }
}
