/*
 * Copyright (c) 2016, 2021 Oracle and/or its affiliates. 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:
//     04/11/2016-2.7 Tomas Kraus
//       - 490677: Initial API and implementation.
package org.eclipse.persistence.testing.tests.nosql;

import static org.junit.Assert.assertTrue;

import java.util.List;
import java.util.Map;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.SynchronizationType;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.IdentityMapAccessor;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.testing.framework.server.JEEPlatform;
import org.eclipse.persistence.testing.framework.server.ServerPlatform;

public class EntityManagerHelper {

    /** Logger. */
    private static final SessionLog LOG = AbstractSessionLog.getLog();

    /** Stores an information if this test is running on a JEE server, or in JSE. */
    static final boolean isOnServer = System.getProperty("TEST_SERVER_PLATFORM") != null;

    /** Stores an information if the data source is JTA or not. */
    static final boolean isJTA = Boolean.getBoolean(System.getProperty("is.JTA"));

    /** Application server platform. */
    static final ServerPlatform serverPlatform = isOnServer ? initServerPlatform() : null;

    /**
     * Initialize application server platform instance.
     * @return Application server platform instance or {@code null} if instance could not be initialized.
     */
    private static ServerPlatform initServerPlatform() {
        final String platformClass = System.getProperty("TEST_SERVER_PLATFORM");
        if (platformClass == null) {
            return new JEEPlatform();
        } else {
            try {
                return (ServerPlatform)Class.forName(platformClass).newInstance();
            } catch (Exception ex) {
                LOG.log(SessionLog.WARNING, String.format(
                        "Could not initiaize ServerPlatform: %s", ex.getLocalizedMessage()));
                return null;
            }
        }
    }

    /**
     * Create a new entity manager for the persistence unit using the properties. The properties will only be used
     * the first time this entity manager is accessed. If in JEE this will create or return the active managed entity
     * manager.
     * @param puName      Name of persistence unit used to create {@link EntityManager}.
     * @param descriptors Additional persistent classes descriptors. Will not be added when running on application
     *                    server.
     * @param mapped      Build mapped property for database host and port pair.
     * @return New {@link EntityManager} instance.
     */
    public static EntityManager createEntityManager(
            final String puName, final List<ClassDescriptor> descriptors, final boolean mapped) {
        final Map<String, String> emProperties = NoSQLProperties.createEMProperties(mapped);
        if (isOnServer && isJTA) {
            if (serverPlatform != null) {
                final EntityManagerFactory emf = serverPlatform.getEntityManagerFactory(puName);
                return emf.createEntityManager(emProperties);
            } else {
                LOG.log(SessionLog.WARNING, String.format(
                        "ServerPlatform is unknown, using default EntityManagerFactory to create EntityManager"));
                return JUnitTestCase.getEntityManagerFactory(puName, emProperties, descriptors)
                        .createEntityManager(null, emProperties);            }
        } else {
            return JUnitTestCase.getEntityManagerFactory(puName, emProperties, descriptors)
                    .createEntityManager(null, emProperties);
        }
    }

    /**
     * Create a new entity manager for the persistence unit using the properties. The properties will only be used
     * the first time this entity manager is accessed. If in JEE this will create or return the active managed entity
     * manager.
     * @param puName      Name of persistence unit used to create {@link EntityManager}.
     * @param mapped      Build mapped property for database host and port pair.
     * @return New {@link EntityManager} instance.
     */
    public static EntityManager createEntityManager(final String puName, final boolean mapped) {
        return createEntityManager(puName, null, mapped);
    }

    /**
     * Create a new entity manager for the persistence unit using the properties. The properties will only be used
     * the first time this entity manager is accessed. If in JEE this will create or return the active managed entity
     * manager.
     * @param puName      Name of persistence unit used to create {@link EntityManager}.
     * @return New {@link EntityManager} instance.
     */
    public static EntityManager createEntityManager(final String puName) {
        return createEntityManager(puName, null, false);
    }

    /**
     * Get database session from entity manager.
     * @param entityManager Entity manager holding the database session.
     * @return Database session from entity manager.
     */
    public static DatabaseSessionImpl getDatabaseSession(final EntityManager entityManager) {
        return ((org.eclipse.persistence.jpa.JpaEntityManager)entityManager).getDatabaseSession();
    }

    /**
     * Begin a transaction on the entity manager. This allows the same code to be used on the server where JTA is used,
     * and will join the EntityManager to the transaction.
     * @param entityManager Entity manager holding the transaction.
     */
    public static void beginTransaction(final EntityManager entityManager) {
        if (serverPlatform != null) {
            serverPlatform.beginTransaction();
            serverPlatform.joinTransaction(entityManager);
        } else {
            entityManager.getTransaction().begin();
        }
    }

    /**
     * Commit a transaction on the entity manager. This allows the same code to be used on the server where JTA is used.
     * @param entityManager Entity manager holding the transaction.
     */
    public static void commitTransaction(final EntityManager entityManager) {
        if (serverPlatform != null) {
            serverPlatform.commitTransaction();
        } else {
            entityManager.getTransaction().commit();
        }
    }

    /**
     * Roll back a transaction on the entity manager. This allows the same code to be used on the server where JTA
     * is used.
     * @param entityManager Entity manager holding the transaction.
     */
    public static void rollbackTransaction(final EntityManager entityManager) {
        if (serverPlatform != null) {
            serverPlatform.rollbackTransaction();
        } else {
            entityManager.getTransaction().rollback();
        }
    }

    /**
     * Check if the transaction in provided entity manager is active.
     * This allows the same code to be used on the server where JTA is used.
     * @param entityManager Entity manager holding the transaction.
     */
    public static boolean isTransactionActive(EntityManager entityManager) {
        if (serverPlatform != null) {
            return serverPlatform.isTransactionActive();
        } else {
            return entityManager.getTransaction().isActive();
        }
    }

    /**
     * Close the entity manager.
     * This allows the same code to be used on the server where managed entity managers are not closed.
     * @param entityManager Entity manager to be closed.
     */
    public static void closeEntityManager(EntityManager entityManager) {
        if (!isOnServer) {
            entityManager.close();
        }
    }

    /**
     * Close the entity manager.
     * If a transaction is active, then roll it back.
     * @param entityManager Entity manager to be closed.
     */
    public static void closeEntityManagerAndTransaction(EntityManager entityManager) {
        if (isTransactionActive(entityManager)) {
            rollbackTransaction(entityManager);
        }
        closeEntityManager(entityManager);
    }

    /**
     * Clear cache for current database session.
     * @param entityManager Entity manager holding the the database session.
     */
    public static void clearCache(final EntityManager entityManager) {
        DatabaseSession session = getDatabaseSession(entityManager);
        if (session != null) {
            IdentityMapAccessor accessor = session.getIdentityMapAccessor();
            if (accessor != null) {
                accessor.initializeAllIdentityMaps();
            } else {
                LOG.log(SessionLog.WARNING, "Could not get IdentityMapAccessor from session");
            }
        } else {
            LOG.log(SessionLog.WARNING, "Could not get session from EntityManager");
        }
    }

    /**
     * Compare persistence objects.
     * Test will fail when compared objects differ.
     * @param obj1 First persistence object.
     * @param obj2 Second persistence object.
     * @param entityManager Entity manager holding the the database session.
     */
    public static void compareObjects(Object obj1, Object obj2, final EntityManager entityManager) {
        AbstractSession dbs = getDatabaseSession(entityManager);
        assertTrue("Objects " + obj1 + " and " + obj2 + " are not equal", dbs.compareObjects(obj1, obj2));
    }

}
