/*
 * Copyright (c) 2011, 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:
//     tware - initial implementation as part of extensibility feature
//     01/11/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     01/16/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     02/04/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     05/26/2016-2.7 Tomas Kraus
//       - 494610: Session Properties map should be Map<String, Object>
package org.eclipse.persistence.internal.jpa;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jakarta.persistence.Cache;
import jakarta.persistence.EntityGraph;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.PersistenceException;
import jakarta.persistence.PersistenceUnitUtil;
import jakarta.persistence.Query;
import jakarta.persistence.SynchronizationType;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.metamodel.Metamodel;

import org.eclipse.persistence.config.ReferenceMode;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException;
import org.eclipse.persistence.internal.indirection.IndirectionPolicy;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.internal.sessions.coordination.MetadataRefreshCommand;
import org.eclipse.persistence.jpa.JpaEntityManagerFactory;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.queries.AttributeGroup;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.FetchGroupTracker;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.UnitOfWork.CommitOrderType;
import org.eclipse.persistence.sessions.broker.SessionBroker;
import org.eclipse.persistence.sessions.coordination.CommandManager;
import org.eclipse.persistence.sessions.factories.SessionManager;
import org.eclipse.persistence.sessions.server.Server;
import org.eclipse.persistence.sessions.server.ServerSession;

/**
 * Wraps our implementation of EntityManagerFactory
 * Most operations are forwarded to the delegate.  This wrapper is used to enable
 * the refreshMetadata functionality which allows you to switch the underlying metadata for
 * an EMF after deploy time.
 * @author tware
 *
 */
public class EntityManagerFactoryImpl implements EntityManagerFactory, PersistenceUnitUtil, JpaEntityManagerFactory {
    protected EntityManagerFactoryDelegate delegate;


    /**
     * Returns the id of the entity. A generated id is not guaranteed to be
     * available until after the database insert has occurred. Returns null if
     * the entity does not yet have an id
     *
     * @return id of the entity
     * @throws IllegalArgumentException
     *             if the entity is found not to be an entity.
     */
    public static Object getIdentifier(Object entity, AbstractSession session) {
        ClassDescriptor descriptor = session.getDescriptor(entity);
        if (descriptor == null) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_persistence_util_non_persistent_class", new Object[] { entity }));
        }
        if (descriptor.getCMPPolicy() != null) {
            return descriptor.getCMPPolicy().createPrimaryKeyInstance(entity, session);
        } else {
            // 308950: Alternatively, CacheImpl.getId(entity) handles a null CMPPolicy case for weaved and unweaved domain object
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_persistence_util_non_persistent_class", new Object[] { entity }));
        }
    }


    /**
     * Determine the load state of an entity belonging to the persistence unit.
     * This method can be used to determine the load state of an entity passed
     * as a reference. An entity is considered loaded if all attributes for
     * which FetchType EAGER has been specified have been loaded. The
     * isLoaded(Object, String) method should be used to determine the load
     * state of an attribute. Not doing so might lead to unintended loading of
     * state.
     *
     * @param entity
     *            whose load state is to be determined
     * @return false if the entity has not been loaded, else true.
     */
    public static Boolean isLoaded(Object entity, AbstractSession session) {
        ClassDescriptor descriptor = session.getDescriptor(entity);
        if (descriptor == null) {
            return null;
        }
        List<DatabaseMapping> mappings = descriptor.getMappings();
        Iterator<DatabaseMapping> i = mappings.iterator();
        while (i.hasNext()) {
            DatabaseMapping mapping = i.next();
            if (!mapping.isLazy() && !isLoaded(entity, mapping.getAttributeName(), mapping)) {
                return false;
            }
        }
        return true;
    }


    /**
     * Determine the load state of a given persistent attribute of an entity
     * belonging to the persistence unit.
     *
     * @param entity
     *            containing the attribute
     * @param attributeName
     *            name of attribute whose load state is to be determined
     * @return false if entity's state has not been loaded or if the attribute
     *         state has not been loaded, otherwise true
     */
    public static Boolean isLoaded(Object entity, String attributeName, AbstractSession session) {
        ClassDescriptor descriptor = session.getDescriptor(entity);
        if (descriptor == null) {
            return null;
        }
        if (descriptor.hasFetchGroupManager()){
            if (!descriptor.getFetchGroupManager().isAttributeFetched(entity, attributeName)){
                return false;
            }
        }
        DatabaseMapping mapping = descriptor.getMappingForAttributeName(attributeName);
        if (mapping == null) {
            return null;
        }
        return isLoaded(entity, attributeName, mapping);
    }

    /**
     * Check whether a named attribute on a given entity with a given mapping
     * has been loaded.
     *
     * This method will check the valueholder or indirect collection for LAZY
     * ForeignReferenceMappings to see if has been instantiated and otherwise
     * check the fetch group.
     *
     */
    public static boolean isLoaded(Object entity, String attributeName, DatabaseMapping mapping) {
        if (mapping.isForeignReferenceMapping()) {
            if (mapping.isLazy()) {
                Object value = mapping.getAttributeValueFromObject(entity);
                IndirectionPolicy policy = ((ForeignReferenceMapping) mapping).getIndirectionPolicy();
                return policy.objectIsInstantiated(value);
            }
        }

        if (entity instanceof FetchGroupTracker) {
            return ((FetchGroupTracker) entity)._persistence_isAttributeFetched(attributeName);
        } else {
            return true;
        }
    }

    /**
     * Will return an instance of the Factory. Should only be called by
     * EclipseLink.
     *
     */
    public EntityManagerFactoryImpl(AbstractSession serverSession) {
        delegate = new EntityManagerFactoryDelegate(serverSession, this);
    }

    public EntityManagerFactoryImpl(EntityManagerSetupImpl setupImpl, Map properties) {
        delegate = new EntityManagerFactoryDelegate(setupImpl, properties, this);
    }

    /**
     * Create a dynamic persistence unit which does not use the persistence.xml.
     * Instead all configuration is driven from the provided persistence unit
     * properties and descriptors.
     */
    public EntityManagerFactoryImpl(String persistenceUnitName, Map<String, Object> properties, List<ClassDescriptor> descriptors) {
        delegate = new EntityManagerFactoryDelegate(persistenceUnitName, properties, descriptors, this);
    }

    /**
     * ADVANCED:
     * Re-bootstrap this factory.  This method will rebuild the EntityManagerFactory.  It should be used
     * in conjunction with a MetadataSource to allow mappings to be changed in a running system.  All existing
     * EntityMangers will continue to function with the old metadata, but new factories will use the new metadata.
     */
    @Override
    public void refreshMetadata(Map<String, Object> properties){
        EntityManagerSetupImpl setupImpl = delegate.getSetupImpl();
        if (setupImpl == null){
            throw PersistenceUnitLoadingException.cannotRefreshEntityManagerFactoryCreatedFromSession(delegate.getServerSession().getName());
        }
        String sessionName = setupImpl.getSessionName();
        Map<String, Object> existingProperties = delegate.getProperties();
        Map<String, Object> deployProperties = new HashMap<>();
        deployProperties.putAll(existingProperties);
        if (properties != null){
            deployProperties.putAll(properties);
        }
        EntityManagerSetupImpl newSetupImpl = setupImpl.refreshMetadata(properties);
        EntityManagerFactoryDelegate oldDelegate = delegate;
        delegate = new EntityManagerFactoryDelegate(newSetupImpl, deployProperties, this);
        // This code has been added to allow validation to occur without actually calling createEntityManager
        // RCM refresh command requires the DEPLOY_ON_STARTUP property is set to true so the listener can be added to the session.
        try{
            if (newSetupImpl.shouldGetSessionOnCreateFactory(deployProperties)) {
                ServerSession session = getServerSession();
                CommandManager rcm = session.getCommandManager();
                if (rcm != null && newSetupImpl.shouldSendMetadataRefreshCommand(deployProperties)) {
                    MetadataRefreshCommand command = new MetadataRefreshCommand(properties);
                    rcm.propagateCommand(command);
                }
                session.setRefreshMetadataListener(newSetupImpl);
            }
        } catch (RuntimeException ex) {
            if(delegate != null) {
                delegate.close();
            } else {
                newSetupImpl.undeploy();
            }
            synchronized(EntityManagerFactoryProvider.emSetupImpls){
                // bring back the old emSetupImpl and session
                EntityManagerFactoryProvider.emSetupImpls.put(sessionName, setupImpl);
                SessionManager.getManager().getSessions().put(sessionName, setupImpl.getSession());
                setupImpl.setIsMetadataExpired(false);
            }
            delegate = oldDelegate;
            throw ex;
        }
    }

    /**
     * INTERNAL: Returns the SessionBroker that the Factory will be using and
     * initializes it if it is not available. This method makes use of the
     * partially constructed session stored in our setupImpl and completes its
     * construction
     * TODO: should throw IllegalStateException if not SessionBroker
     */
    @Override
    public SessionBroker getSessionBroker() {
        return delegate.getSessionBroker();
    }

    /**
     * INTERNAL: Returns the ServerSession that the Factory will be using and
     * initializes it if it is not available. This method makes use of the
     * partially constructed session stored in our setupImpl and completes its
     * construction
     */
    @Override
    public ServerSession getServerSession() {
        return delegate.getServerSession();
    }

    /**
     * Closes this factory, releasing any resources that might be held by this
     * factory. After invoking this method, all methods on the instance will
     * throw an {@link IllegalStateException}, except for {@link #isOpen}, which
     * will return <code>false</code>.
     */
    @Override
    public synchronized void close() {
        delegate.close();
    }

    /**
     * Indicates whether or not this factory is open. Returns <code>true</code>
     * until a call to {@link #close} is made.
     */
    @Override
    public boolean isOpen() {
        return delegate.isOpen();
    }

    /**
     * PUBLIC: Returns an EntityManager for this deployment.
     */
    @Override
    public EntityManager createEntityManager() {
        return createEntityManagerImpl(null, null);
    }

    /**
     * PUBLIC: Returns an EntityManager for this deployment.
     */
    @Override
    public EntityManager createEntityManager(Map properties) {
        return createEntityManagerImpl(properties, null);
    }

    @Override
    public EntityManager createEntityManager(SynchronizationType synchronizationType) {
        return createEntityManagerImpl(null, synchronizationType);
    }

    @Override
    public EntityManager createEntityManager(SynchronizationType synchronizationType, Map map) {
        return createEntityManagerImpl(map, synchronizationType);
    }

    protected EntityManagerImpl createEntityManagerImpl(Map properties, SynchronizationType syncType) {
        EntityManagerSetupImpl setupImpl = delegate.getSetupImpl();

        if (setupImpl != null) {
            if (setupImpl.isMetadataExpired()) {
                String sessionName = setupImpl.getSessionName();
                EntityManagerSetupImpl storedImpl = null;
                synchronized (EntityManagerFactoryProvider.emSetupImpls){
                    storedImpl = EntityManagerFactoryProvider.emSetupImpls.get(sessionName);
                }
                if (storedImpl != null) {
                    delegate = new EntityManagerFactoryDelegate(storedImpl, delegate.getProperties(), this);
                }
            }
        }

        return delegate.createEntityManagerImpl(properties, syncType);
    }

    /**
     * Gets the underlying implementation of the EntityManagerFactory.
     * This method will return a version of EntityManagerFactory that is
     * based on the available metadata at the time it is called.  Future calls
     * to refresh will not affect that metadata on this EntityManagerFactory.
     */
    @Override
    public EntityManagerFactoryDelegate unwrap(){
        return delegate;
    }

    protected void verifyOpen() {
        delegate.verifyOpen();
    }

    /**
     * The method return user defined property passed in from
     * EntityManagerFactory.
     */
    public Object getProperty(String name) {
        return delegate.getProperty(name);
    }

    /**
     * Return default join existing transaction property, allows reading through
     * write connection.
     */
    public boolean getBeginEarlyTransaction() {
        return delegate.getBeginEarlyTransaction();
    }

    /**
     * Set default join existing transaction property, allows reading through
     * write connection.
     */
    public void setBeginEarlyTransaction(boolean beginEarlyTransaction) {
        delegate.setBeginEarlyTransaction(beginEarlyTransaction);
    }

    /**
     * Return default property, allows flush before query to be avoided.
     */
    public FlushModeType getFlushMode() {
        return delegate.getFlushMode();
    }

    /**
     * Set default property, allows flush before query to be avoided.
     */
    public void setFlushMode(FlushModeType flushMode) {
        delegate.setFlushMode(flushMode);
    }

    /**
     * Return default property, allows weak unit of work references.
     */
    public ReferenceMode getReferenceMode() {
        return delegate.getReferenceMode();
    }

    /**
     * Set default property, allows weak unit of work references.
     */
    public void setReferenceMode(ReferenceMode referenceMode) {
        delegate.setReferenceMode(referenceMode);
    }

    /**
     * Return default property to avoid resuming unit of work if going to be
     * closed on commit anyway.
     */
    public boolean getCloseOnCommit() {
        return delegate.getCloseOnCommit();
    }

    /**
     * Set default property to avoid resuming unit of work if going to be closed
     * on commit anyway.
     */
    public void setCloseOnCommit(boolean closeOnCommit) {
        delegate.setCloseOnCommit(closeOnCommit);
    }

    /**
     * Return default property to avoid discover new objects in unit of work if
     * application always uses persist.
     */
    public boolean getPersistOnCommit() {
        return delegate.getPersistOnCommit();
    }

    /**
     * Return interface providing access to utility methods for the persistence
     * unit.
     *
     * @return PersistenceUnitUtil interface
     * @throws IllegalStateException
     *             if the entity manager factory has been closed.
     */
    @Override
    public PersistenceUnitUtil getPersistenceUnitUtil() {
        return delegate.getPersistenceUnitUtil();
    }

    /**
     * Set default property to avoid discover new objects in unit of work if
     * application always uses persist.
     */
    public void setPersistOnCommit(boolean persistOnCommit) {
        delegate.setPersistOnCommit(persistOnCommit);
    }

    /**
     * Return default property to avoid discover new objects in unit of work if
     * application always uses persist.
     */
    public boolean getCommitWithoutPersistRules() {
        return delegate.getCommitWithoutPersistRules();
    }

    /**
     * Set default property to avoid discover new objects in unit of work if
     * application always uses persist.
     */
    public void setCommitWithoutPersistRules(boolean commitWithoutPersistRules) {
        delegate.setCommitWithoutPersistRules(commitWithoutPersistRules);
    }

    /**
     * Return the default FlashClearCache mode to be used. Relevant only in case
     * call to flush method followed by call to clear method.
     *
     * @see org.eclipse.persistence.config.FlushClearCache
     */
    public String getFlushClearCache() {
        return delegate.getFlushClearCache();
    }

    /**
     * Set the default FlashClearCache mode to be used. Relevant only in case
     * call to flush method followed by call to clear method.
     *
     * @see org.eclipse.persistence.config.FlushClearCache
     */
    public void setFlushClearCache(String flushClearCache) {
        delegate.setFlushClearCache(flushClearCache);
    }

    /**
     * Return the default to determine if does-exist should be performed on
     * persist.
     */
    public boolean shouldValidateExistence() {
        return delegate.shouldValidateExistence();
    }

    /**
     * Set the default to determine if does-exist should be performed on
     * persist.
     */
    public void setShouldValidateExistence(boolean shouldValidateExistence) {
        delegate.setShouldValidateExistence(shouldValidateExistence);
    }

    /**
     * Access the cache that is associated with the entity manager
     * factory (the "second level cache").
     * @return instance of the <code>Cache</code> interface
     * @throws IllegalStateException if the entity manager factory has been closed
     * @see jakarta.persistence.EntityManagerFactory#getCache()
     * @since Java Persistence 2.0
     */
    @Override
    public Cache getCache() {
        return delegate.getCache();
    }

    /**
     * @see jakarta.persistence.EntityManagerFactory#getProperties()
     * @since Java Persistence API 2.0
     */
    @Override
    public Map<String, Object> getProperties() {
        return delegate.getProperties();
    }

    @Override
    public DatabaseSessionImpl getDatabaseSession() {
        return delegate.getDatabaseSession();
    }
    /**
     * @see jakarta.persistence.EntityManagerFactory#getCriteriaBuilder()
     * @since Java Persistence 2.0
     */
    @Override
    public CriteriaBuilder getCriteriaBuilder() {
        return delegate.getCriteriaBuilder();
    }

    /**
     * Return an instance of Metamodel interface for access to the metamodel of
     * the persistence unit.
     *
     * @return Metamodel instance
     * @throws IllegalStateException
     *             if the entity manager factory has been closed.
     * @see jakarta.persistence.EntityManagerFactory#getMetamodel()
     * @since Java Persistence 2.0
     */
    @Override
    public Metamodel getMetamodel() {
        return delegate.getMetamodel();
    }

    /**
     * INTERNAL: Convenience function to allow us to reset the Metamodel in the
     * possible case that we want to regenerate it. This function is outside of
     * the JPA 2.0 specification.
     *
     * @since Java Persistence 2.0
     */
    public void setMetamodel(Metamodel aMetamodel) {
        delegate.setMetamodel(aMetamodel);
    }

    /**
     * Determine the load state of a given persistent attribute of an entity
     * belonging to the persistence unit.
     *
     * @param entity
     *            containing the attribute
     * @param attributeName
     *            name of attribute whose load state is to be determined
     * @return false if entity's state has not been loaded or if the attribute
     *         state has not been loaded, otherwise true
     */
    @Override
    public boolean isLoaded(Object entity, String attributeName) {
        return delegate.isLoaded(entity, attributeName);
    }

    /**
     * Determine the load state of an entity belonging to the persistence unit.
     * This method can be used to determine the load state of an entity passed
     * as a reference. An entity is considered loaded if all attributes for
     * which FetchType EAGER has been specified have been loaded. The
     * isLoaded(Object, String) method should be used to determine the load
     * state of an attribute. Not doing so might lead to unintended loading of
     * state.
     *
     * @param entity
     *            whose load state is to be determined
     * @return false if the entity has not been loaded, else true.
     */
    @Override
    public boolean isLoaded(Object entity) {
        return delegate.isLoaded(entity);
    }

    /**
     * Returns the id of the entity. A generated id is not guaranteed to be
     * available until after the database insert has occurred. Returns null if
     * the entity does not yet have an id
     *
     * @return id of the entity
     * @throws IllegalStateException
     *             if the entity is found not to be an entity.
     */
    @Override
    public Object getIdentifier(Object entity) {
        return delegate.getIdentifier(entity);
    }

    /**
     * Return if updates should be ordered by primary key to avoid possible database deadlocks.
     */
    public CommitOrderType getCommitOrder() {
        return delegate.getCommitOrder();
    }

    /**
     * Set updates should be ordered by primary key to avoid possible database deadlocks.
     */
    public void setCommitOrder(CommitOrderType commitOrder) {
        delegate.setCommitOrder(commitOrder);
    }

    @Override
    public void addNamedQuery(String name, Query query) {
        QueryImpl queryImpl = query.unwrap(QueryImpl.class);
        DatabaseQuery unwrapped = (DatabaseQuery) queryImpl.getDatabaseQueryInternal().clone();
        if (queryImpl.lockMode != null){
            ((ObjectLevelReadQuery)unwrapped).setLockModeType(queryImpl.lockMode.name(), getServerSession());
        }
        if (unwrapped.isReadQuery()){
            ((ReadQuery)unwrapped).setInternalMax((queryImpl.getMaxResultsInternal()));
            ((ReadQuery)unwrapped).setFirstResult((queryImpl.getFirstResult()));
        }
        this.getServerSession().addQuery(name, unwrapped, true);
    }

    @Override
    public <T> T unwrap(Class<T> cls) {
        if (cls.equals(JpaEntityManagerFactory.class) || cls.equals(EntityManagerFactoryImpl.class)) {
            return (T) this;
        }else if (cls.equals(EntityManagerFactoryDelegate.class)) {
            return (T) this.delegate;
        }else if (cls.equals(Session.class) || cls.equals(AbstractSession.class)) {
            return (T) this.delegate.getAbstractSession();
        } else if (cls.equals(DatabaseSession.class) || cls.equals(DatabaseSessionImpl.class)) {
            return (T) this.getDatabaseSession();
        } else if (cls.equals(Server.class) || cls.equals(ServerSession.class)) {
            return (T) this.getServerSession();
        } else if (cls.equals(SessionBroker.class)) {
            return (T) this.getSessionBroker();
        }
        throw new PersistenceException(ExceptionLocalization.buildMessage("unable_to_unwrap_jpa", new String[]{EntityManagerFactory.class.getName(),cls.getName()}));
    }

    @Override
    public <T> void addNamedEntityGraph(String graphName, EntityGraph<T> entityGraph) {
        AttributeGroup group = ((EntityGraphImpl)entityGraph).getAttributeGroup().clone();
        group.setName(graphName);
        this.getServerSession().getAttributeGroups().put(graphName, group);
        this.getServerSession().getDescriptor(((EntityGraphImpl)entityGraph).getClassType()).addAttributeGroup(group);
    }

}
