/*
 * Copyright (c) 1998, 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.jpa;

import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Query;
import org.eclipse.persistence.internal.jpa.*;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.jpa.JpaEntityManager;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.server.Server;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.sessions.broker.SessionBroker;
import org.eclipse.persistence.sessions.factories.SessionFactory;
import org.eclipse.persistence.queries.FetchGroupTracker;


/**
 * This sample illustrates the JPA helper methods that may be of use
 * to EclipseLink customers attempting to leverage EclipseLink specific functionality.
 *
 * @author dclarke, gpelletie
 */
public class JpaHelper {

    private JpaHelper() {
    }

    /**
     * Verify if the JPA provider is EclipseLink. If you are in a container
     * and not in a transaction this method may incorrectly return false.
     * It is always more reliable to check isEclipseLink on the EMF or Query.
     */
    public static boolean isEclipseLink(jakarta.persistence.EntityManager em) {
        return getEntityManager(em) != null;
    }

    /**
     * Verify if the JPA provider is EclipseLink
     */
    public static boolean isEclipseLink(EntityManagerFactory emf) {
        try {
            getEntityManagerFactory(emf);
        } catch (IllegalArgumentException iae) {
            return false;
        }

        return true;
    }

    /**
     * Verify if the JPA provider is EclipseLink
     */
    public static boolean isEclipseLink(Query query) {
        return query instanceof JpaQuery;
    }

    /**
     * Determine if the JPA query is a EclipseLink ReportQuery. Useful for
     * frameworks that want to determine which get_X_Query method they can
     * safely invoke.
     */
    public static boolean isReportQuery(Query query) {
        return isEclipseLink(query) && getDatabaseQuery(query).isReportQuery();
    }

    /**
     * Access the internal EclipseLink query wrapped within the JPA query. A
     * EclipseLink JPA created from JP QL  contains a ReportQuery if multiple
     * items or a non-entity type is being returned. This method will fail
     * if a single entity type is being returned as the query is a ReadAllQuery.
     *
     * @see JpaHelper#getReadAllQuery
     */
    public static ReportQuery getReportQuery(Query query) {
        DatabaseQuery dbQuery = getDatabaseQuery(query);
        if (dbQuery.isReportQuery()) {
            return (ReportQuery)dbQuery;
        }

        throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_helper_invalid_report_query" + query.getClass()));
    }

    /**
     * Access the internal EclipseLink query wrapped within the JPA query.
     */
    public static DatabaseQuery getDatabaseQuery(Query query) {
        if (query instanceof JpaQuery) {
            return ((JpaQuery)query).getDatabaseQuery();
        }

        throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_helper_invalid_query" + query.getClass()));
    }

    /**
     * Access the internal EclipseLink query wrapped within the JPA query. A EclipseLink
     * JPA created from JP QL only contains a ReadAllQuery if only a single entity
     * type is being returned.
     *
     * A ReadAllQuery is the super class of a ReportQuery so this method will
     * always work for either a ReportQuery or ReadAllQuery.
     */
    public static ReadAllQuery getReadAllQuery(Query query) {
        DatabaseQuery dbQuery = getDatabaseQuery(query);
        if (dbQuery.isReadAllQuery()) {
            return (ReadAllQuery)dbQuery;
        }

        throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_helper_invalid_read_all_query" + query.getClass()));
    }

    /**
     * Create a EclipseLink JPA query dynamically given a EclipseLink query.
     */
    public static Query createQuery(DatabaseQuery query, jakarta.persistence.EntityManager em) {
        return getEntityManager(em).createQuery(query);
    }

    /**
     * Convert a JPA entityManager into a EclipseLink specific one. This will work
     * both within a JavaSE deployment as well as within a container where the
     * EntityManager may be wrapped.
     *
     * In the case where the container is not in a transaction it may return null
     * for its delegate. When this happens the only way to access an EntityManager
     * is to use the EntityManagerFactory to create a temporary one where the
     * application manage its lifecycle.
     */
    public static JpaEntityManager getEntityManager(jakarta.persistence.EntityManager entityManager) {
        if (entityManager instanceof JpaEntityManager) {
            return (JpaEntityManager)entityManager;
        }

        if (entityManager.getDelegate() != null) {
            return getEntityManager((jakarta.persistence.EntityManager)entityManager.getDelegate());
        }

        return null;
    }

    /**
     * Given a JPA EntityManagerFactory attempt to cast it to a EclipseLink EMF.
     *
     * Although this method currently returns an instance of EntityManagerFactoryImpl, it
     * is recommended that users cast to JpaEntityManagerFactory.  Future versions of EclipseLink will
     * return that interface from this method instead
     *
     * @see JpaEntityManagerFactory
     * @deprecated
     */
    @Deprecated
    public static EntityManagerFactoryImpl getEntityManagerFactory(EntityManagerFactoryImpl emf) {
        return (emf);
    }

    /**
     * Given a JPA EntityManagerFactory attempt to cast it to a EclipseLink EMF.
     *
     * @see JpaEntityManagerFactory
     */
    public static JpaEntityManagerFactory getEntityManagerFactory(EntityManagerFactory emf) {
        if (emf instanceof JpaEntityManagerFactory) {
            return ((JpaEntityManagerFactory)emf);
        }
        throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_helper_invalid_entity_manager_factory", new Object[]{emf.getClass()}));
    }

    /**
     * Given an EntityManager return the EntityManagerFactory that created it.  This method must be called
     * on an open entity manager and will return null if called on a closed entityManager.
     *
     * This method will return null for non-EclipseLink EntityManagers.
     *
     * @see JpaEntityManagerFactory
     */
    public static JpaEntityManagerFactory getEntityManagerFactory(jakarta.persistence.EntityManager em) {
        JpaEntityManager entityManager = getEntityManager(em);
        if (entityManager != null){
            if (entityManager.getEntityManagerFactory() != null){
                return ((EntityManagerFactoryDelegate)entityManager.getEntityManagerFactory()).getOwner();
            }
        }
        return null;
    }

    /**
     * Retrieve the shared database session from the EMF.
     */
    public static DatabaseSession getDatabaseSession(EntityManagerFactory emf) {
        return getEntityManagerFactory(emf).getDatabaseSession();
    }

    /**
     * Retrieve the shared server session from the EMF.
     */
    public static Server getServerSession(EntityManagerFactory emf) {
        return getEntityManagerFactory(emf).getServerSession();
    }

    /**
     * Retrieve the shared session broker from the EMF.
     */
    public static SessionBroker getSessionBroker(EntityManagerFactory emf) {
        return getEntityManagerFactory(emf).getSessionBroker();
    }

    /**
     * Create a EclipseLink EMF given a ServerSession that has already been created
     * and logged in.
     */
    public static jakarta.persistence.EntityManagerFactory createEntityManagerFactory(Server session) {
        return new EntityManagerFactoryImpl((ServerSession)session);
    }

    /**
     * Create a EclipseLink EMF using a session name and sessions.xml. This is
     * equivalent to using the EclipseLink.session-xml and EclipseLink.session-name PU
     * properties with the exception that no persistence.xml is required.
     *
     * The application would be required to manage this singleton EMF.
     */
    public static EntityManagerFactory createEntityManagerFactory(String sessionName) {
        SessionFactory sf = new SessionFactory(sessionName);
        // Verify that shared session is a ServerSession
        return new EntityManagerFactoryImpl((ServerSession)sf.getSharedSession());
    }



    /**
     * If the object has a fetch group then the whole object is read in.
     */
    public static void loadUnfetchedObject(FetchGroupTracker entity) {
        if(entity._persistence_getFetchGroup() != null) {
            EntityManagerImpl.processUnfetchedAttribute(entity, null);
        }
    }

}
