/*
 * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2005, 2015 SAP. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     SAP - initial API and implementation

package org.eclipse.persistence.testing.tests.wdf.jpa1.entitymanager;

import javax.naming.NamingException;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;

import org.junit.Assert;

import org.eclipse.persistence.testing.framework.wdf.AbstractBaseTest;
import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.framework.wdf.Skip;
import org.eclipse.persistence.testing.framework.wdf.ToBeInvestigated;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Department;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Test;

// we cannot close the JTA EntityManagerFactory -> makes further tests impossible
public class TestEntityManagerFactory extends JPA1Base {

    @Test
    /**
     * just for the case that all other methods are skipped
     */
    public void dummyTestMethod() {
        return;
    }

    @Test()
    @Skip(server=true)
    public void testEntityManagerFactoryClose() throws NamingException {
        final boolean closingEmfThrowsException = AbstractBaseTest.isInsideEngine();
        final JPAEnvironment env = getEnvironment();
        final EntityManagerFactory emf = env.createNewEntityManagerFactory();
        final EntityManager em = emf.createEntityManager();
        try {
            emf.close();
        } catch (IllegalStateException e) {
            if (closingEmfThrowsException) {
                return;
            } else {
                throw e;
            }
        }
        verify(!emf.isOpen(), "EntityManagerFactory not closed");
        verify(!em.isOpen(), "EntityManager not closed");
        try {
            em.contains(new Department(1, "dummy"));
            flop("operation on a closed EntityManager did not throw IllegalStateException");
            em.close();
        } catch (IllegalStateException e) {
            // $JL-EXC$ expected behavior
            Assert.assertTrue(true);
        }
    }

    @Test
    @ToBeInvestigated
    public void testEntityManagerFactoryCloseActiveTransaction() throws NamingException {
        final boolean closingEmfThrowsException = AbstractBaseTest.isInsideEngine();
        final JPAEnvironment env = getEnvironment();
        final EntityManagerFactory emf = env.createNewEntityManagerFactory();
        final EntityManager em = emf.createEntityManager();
        Department dep1 = new Department(11, "Muggles");
        Department dep2 = new Department(12, "Wizards");
        env.beginTransaction(em);
        em.persist(dep1);
        env.commitTransactionAndClear(em);
        env.beginTransaction(em);
        dep1 = em.find(Department.class, dep1.getId());
        em.persist(dep2);
        try {
            emf.close(); // persistence context should remain active
        } catch (IllegalStateException e) {
            if (closingEmfThrowsException) {
                closeEntityManager(em);
                return;
            } else {
                throw e;
            }
        }
        try {
            em.contains(dep1); // should not work any longer
            flop("operation on a closed entity manager did not throw IllegalStateException");
            em.close();
        } catch (IllegalStateException e) {
            // $JL-EXC$ expected behavior
            Assert.assertTrue(true);
        }
        env.rollbackTransaction(em);
        env.beginTransaction(em);
        verify(!emf.isOpen(), "EntityManagerFactory not closed");
        verify(!em.isOpen(), "EntityManager not closed");
        try {
            em.contains(new Department(1, "dummy"));
            flop("operation on a closed EntityManager did not throw IllegalStateException");
            em.close();
        } catch (IllegalStateException e) {
            // $JL-EXC$ expected behavior
            Assert.assertTrue(true);
        }
    }
}
