/*
 * 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).getConstructor().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));
    }

}
