/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2018 IBM Corporation. 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
//     06/30/2010-2.1.1 Michael O'Brien
//       - 316513: Enable JMX MBean functionality for JBoss, Glassfish and WebSphere in addition to WebLogic
//       Move JMX MBean generic registration code up from specific platforms
//       add new isRuntimeServicesEnabledDefault()
//       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
//     12/18/2014-2.6 Rick Curtis
//       - 455690: Move JNDIConnector lookup type to ServerPlatform.
//     08/29/2016 Jody Grassel
//       - 500441: Eclipselink core has System.getProperty() calls that are not potentially executed under doPriv()
package org.eclipse.persistence.platform.server;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.sql.SQLException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import jakarta.persistence.spi.PersistenceUnitInfo;

import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.helper.JPAClassLoaderHolder;
import org.eclipse.persistence.internal.localization.ToStringLocalization;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.ExternalTransactionController;
import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.transaction.JTA11TransactionController;

/**
 * PUBLIC:
 * Implementation of org.eclipse.persistence.platform.server.ServerPlatform
 * <p>
 * This is the abstract superclass of all platforms for all servers. Each DatabaseSession
 * contains an instance of the receiver, to help the DatabaseSession determine:
 * <ul>
 * <li> Which external transaction controller to use
 * <li> Whether or not to enable JTA (external transaction control)
 * <li> How to register/unregister for runtime services (JMX/MBean)
 * <li> Whether or not to enable runtime services
 * <li> How to launch container Threads
 * </ul>
 * <p>
 * Subclasses already exist to provide configurations for Oc4J, WebLogic, JBoss, NetWeaver, GlassFish and WebSphere.
 * <p>
 * If the user wants a different external transaction controller class or
 * to provide some different behavior than the provided ServerPlatform(s), we recommend
 * subclassing org.eclipse.persistence.platform.server.ServerPlatformBase (or a subclass),
 * and overriding:
 * <ul>
 * <li>ServerPlatformBase.getExternalTransactionControllerClass()
 * <li>ServerPlatformBase.registerMBean()
 * <li>ServerPlatformBase.unregisterMBean()
 * </ul>
 * for the desired behavior.
 *
 * @see org.eclipse.persistence.platform.server.ServerPlatform
 */
public abstract class ServerPlatformBase implements ServerPlatform {

    // Secondary override properties can be set to disable MBean registration
    /** This System property "eclipselink.register.dev.mbean" when set to true will enable registration/unregistration of the DevelopmentServices MBean */
    public static final String JMX_REGISTER_DEV_MBEAN_PROPERTY = "eclipselink.register.dev.mbean";
    /** This System property "eclipselink.register.run.mbean" when set to true will enable registration/unregistration of the RuntimeServices MBean */
    public static final String JMX_REGISTER_RUN_MBEAN_PROPERTY = "eclipselink.register.run.mbean";
    /**
     * INTERNAL:
     * Answer "unknown" as a default for platforms that do not implement getModuleName()
     */
    public static final String DEFAULT_SERVER_NAME_AND_VERSION = ToStringLocalization.buildMessage("unknown");

    /**
     * INTERNAL:
     * isRuntimeServicesEnabled: Determines if the JMX Runtime Services will be deployed at runtime
     */
    private boolean isRuntimeServicesEnabled;

    // Only a "false" value will disable MBean registration for both beans
    protected boolean shouldRegisterDevelopmentBean = true;
    protected boolean shouldRegisterRuntimeBean = true;


    /**
     * externalTransactionControllerClass: This is a user-specifiable class defining the class
     * of external transaction controller to be set into the DatabaseSession
     */
    protected Class<? extends ExternalTransactionController> externalTransactionControllerClass;


    /**
     * INTERNAL:
     * isJTAEnabled: Determines if the external transaction controller will be populated into the DatabaseSession
     * at runtime
     */
    private boolean isJTAEnabled;

    /**
     * INTERNAL:
     * isCMP: true if the container created the server platform, because we're configured
     * for CMP.
     */
    private boolean isCMP;

    /**
     * INTERNAL:
     * databaseSession: The instance of DatabaseSession that I am helping.
     */
    private DatabaseSession databaseSession;

    /**
     * INTERNAL:
     * Server name and version.
     */
    protected String serverNameAndVersion;

    /**
     * Allow the thread pool size to be configured.
     */
    protected int threadPoolSize = 32;

    /**
     * Allow pooling of threads for asynchronous processing in RCM and other areas.
     */
    protected volatile ExecutorService threadPool;

    /**
     * INTERNAL: Default Constructor: Initialize so that runtime services and
     * JTA are enabled. Set the DatabaseSession that I will be helping.
     *
     * @param newDatabaseSession
     *            The instance of DatabaseSession that I am helping.
     */
    protected ServerPlatformBase(DatabaseSession newDatabaseSession) {
        this.isJTAEnabled = true;
        // Default JMX support to false for all sub-platforms except those that override this flag
        this.isRuntimeServicesEnabled = isRuntimeServicesEnabledDefault();
        this.databaseSession = newDatabaseSession;
        this.setIsCMP(false);
        // Enable users to disable or enable (default) MBean registration
        String shouldRegisterRuntimeBeanProperty = PrivilegedAccessHelper.getSystemProperty(JMX_REGISTER_RUN_MBEAN_PROPERTY);
        if(null != shouldRegisterRuntimeBeanProperty) {
            if(shouldRegisterRuntimeBeanProperty.toLowerCase().indexOf("false") > -1) {
                shouldRegisterRuntimeBean = false;
            }
            if(shouldRegisterRuntimeBeanProperty.toLowerCase().indexOf("true") > -1) {
                shouldRegisterRuntimeBean = true;
            }
        }
        String shouldRegisterDevelopmentBeanProperty = PrivilegedAccessHelper.getSystemProperty(JMX_REGISTER_DEV_MBEAN_PROPERTY);
        if(null != shouldRegisterDevelopmentBeanProperty) {
            if(shouldRegisterDevelopmentBeanProperty.toLowerCase().indexOf("false") > -1) {
                shouldRegisterDevelopmentBean = false;
            }
            if(shouldRegisterDevelopmentBeanProperty.toLowerCase().indexOf("true") > -1) {
                shouldRegisterDevelopmentBean = true;
            }
        }
    }

    /**
     * INTERNAL: configureProfiler(): set default performance profiler used in this server.
     */
    public void configureProfiler(org.eclipse.persistence.sessions.Session session) {
        return;
    }

    /**
     * INTERNAL: getDatabaseSession(): Answer the instance of DatabaseSession the receiver is helping.
     *
     * @return DatabaseSession databaseSession
     */
    @Override
    public DatabaseSession getDatabaseSession() {
        return this.databaseSession;
    }

    /**
     * PUBLIC: getServerNameAndVersion(): Talk to the relevant server class library, and get the server name
     * and version
     *
     * @return String serverNameAndVersion
     */
    @Override
    public String getServerNameAndVersion() {
        if(this.serverNameAndVersion == null) {
            this.initializeServerNameAndVersion();
        }
        return this.serverNameAndVersion;
    }

    /**
     * INTERNAL: initializeServerNameAndVersion(): Talk to the relevant server class library, and get the server name
     * and version
     *
     * Default is "unknown"
     */
    protected void initializeServerNameAndVersion() {
        this.serverNameAndVersion = DEFAULT_SERVER_NAME_AND_VERSION;
    }

    /**
     * INTERNAL: getModuleName(): Answer the name of the module (jar name) that my session
       * is associated with.
       * Answer "unknown" if there is no module name available.
       *
       * Default behavior is to return "unknown".
     *
     * @return String moduleName
     */
    @Override
    public String getModuleName() {
        return DEFAULT_SERVER_NAME_AND_VERSION;
    }

    /**
     * INTERNAL: getExternalTransactionControllerClass(): Answer the class of external transaction controller to use
     * For this server platform. This is read-only.
     *
       * If the user wants a different external transaction controller class than the provided ServerPlatform(s),
       * we recommend subclassing org.eclipse.persistence.platform.server.ServerPlatformBase (or a subclass),
       * and overriding:
       *
       * ServerPlatformBase.getExternalTransactionControllerClass()
       *
       * for the desired behavior.
     *
     * @return Class externalTransactionControllerClass
     *
     * @see org.eclipse.persistence.transaction.JTATransactionController
     * @see #isJTAEnabled()
     * @see #disableJTA()
     */
    @Override
    public abstract Class<? extends ExternalTransactionController> getExternalTransactionControllerClass();

    /**
     * INTERNAL: setExternalTransactionControllerClass(Class newClass): Set the class of external
     * transaction controller to use in the DatabaseSession.
     * This is defined by the user via the sessions.xml.
     *
     * @see org.eclipse.persistence.transaction.JTATransactionController
     * @see #isJTAEnabled()
     * @see #disableJTA()
     * @see #initializeExternalTransactionController()
     */
    @Override
    public void setExternalTransactionControllerClass(Class<? extends ExternalTransactionController> newClass) {
        this.externalTransactionControllerClass = newClass;
    }

    /**
     * INTERNAL: initializeExternalTransactionController(): Populate the DatabaseSession's
     * external transaction controller with an instance of my transaction controller class.
     *
     * To change the external transaction controller class, we recommend creating a subclass of
     * ServerPlatformBase, and overriding getExternalTransactionControllerClass().
     */
    @Override
    public void initializeExternalTransactionController() {
        this.ensureNotLoggedIn();

        //BUG 3975114: Even if JTA is disabled, override if we're in CMP
        //JTA must never be disable during CMP (WLS/Oc4j)
        if (!isJTAEnabled() && !isCMP()) {
            return;
        }
        //BUG 3975114: display a warning if JTA is disabled and we're in CMP
        if (!isJTAEnabled() && isCMP()) {
            getDatabaseSession().getSessionLog().log(SessionLog.WARNING, SessionLog.EJB, "jta_cannot_be_disabled_in_cmp", null, true);
        }

        //check if the transaction controller class is overridden by a preLogin or equivalent,
        //or if the transaction controller was already defined, in which case they should have written
        //a subclass. Show a warning
        try {
            if (getDatabaseSession().getExternalTransactionController() != null) {
                this.externalTransactionControllerNotNullWarning();
                return;
            }
            ExternalTransactionController controller = null;
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    controller = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(this.getExternalTransactionControllerClass()));
                } catch (PrivilegedActionException exception) {
                    Exception throwableException = exception.getException();
                    if (throwableException instanceof InstantiationException) {
                        throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName());
                    } else {
                        throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName());
                    }
                }
            } else {
                controller = PrivilegedAccessHelper.newInstanceFromClass(this.getExternalTransactionControllerClass());
            }
            getDatabaseSession().setExternalTransactionController(controller);
        } catch (InstantiationException instantiationException) {
            throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName());
        } catch (IllegalAccessException illegalAccessException) {
            throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName());
        }
    }

    /**
     * INTERNAL: externalTransactionControllerNotNullWarning():
     * When the external transaction controller is being initialized, we warn the developer
     * if they have already defined the external transaction controller in some way other
     * than subclassing ServerPlatformBase.
     *
     * @see #getExternalTransactionControllerClass()
     */
    protected void externalTransactionControllerNotNullWarning() {
        ((DatabaseSessionImpl)getDatabaseSession()).warning("External_transaction_controller_not_defined_by_server_platform", SessionLog.EJB);
    }

    /**
     * INTERNAL: isJTAEnabled(): Answer true if the DatabaseSession's external transaction controller class will
     * be populated with my transaction controller class at runtime. If the transaction controller class is
     * overridden in the DatabaseSession, my transaction controller class will be ignored.
     *
     * Answer true if TopLink will be configured to register for callbacks for beforeCompletion and afterCompletion.
     *
     * @return boolean isJTAEnabled
     * @see #getExternalTransactionControllerClass()
     * @see #disableJTA()
     */
    @Override
    public boolean isJTAEnabled() {
        return this.isJTAEnabled;
    }

    /**
     * INTERNAL:
     * Check whether JTA 1.1 API is available.
     *
     * @return value of {@code true} when JTA 1.1 API is available or {@code false} otherwise.
     */
    public boolean isJTA11() {
        Context context = null;
        try {
            context = new InitialContext();
            if (context.lookup(JTA11TransactionController.JNDI_TRANSACTION_SYNCHRONIZATION_REGISTRY) != null) {
                return true;
            }
        } catch (NamingException ex) {
            // Ignore
        } finally {
            if (context != null) {
                try {
                    context.close();
                } catch (Exception ex) {
                    // Ignore
                }
            }
        }
        return false;
    }

    /**
     * INTERNAL:
     * isRuntimeServicesEnabledDefault(): Answer true if the JMX/MBean providing runtime services for
     * the receiver's DatabaseSession will be deployed at runtime.
     * Provide the default value for {@link #isRuntimeServicesEnabled()} for a
     * ServerPlatform. By default this is <code>false</code> but some platforms
     * can choose to have MBeans deployed by default.
     */
    @Override
    public boolean isRuntimeServicesEnabledDefault() {
        return false;
    }

    /**
     * INTERNAL:
     * isRuntimeServicesEnabled(): Answer true if the JMX/MBean providing runtime services for
     * the receiver's DatabaseSession will be deployed at runtime.
     *
     * @return boolean isRuntimeServicesEnabled
     * @see #disableRuntimeServices()
     */
    @Override
    public boolean isRuntimeServicesEnabled() {
        return this.isRuntimeServicesEnabled;
    }

    /**
     * INTERNAL: disableRuntimeServices(): Configure the receiver such that no JMX/MBean will be registered
     * to provide runtime services for my DatabaseSession at runtime.
     *
     * @see #isRuntimeServicesEnabled()
     */
    @Override
    public void disableRuntimeServices() {
        this.ensureNotLoggedIn();
        this.isRuntimeServicesEnabled = false;
    }

    /**
     * INTERNAL:
     * enableRuntimeServices(): Configure the receiver such that JMX/MBeans will be registered
     * to provide runtime services for my DatabaseSession at runtime.
     *
     * @see #isRuntimeServicesEnabled()
     * @since EclipseLink 2.2.0
     */
    public void enableRuntimeServices() {
        this.ensureNotLoggedIn();
        this.isRuntimeServicesEnabled = true;
    }


    /**
     * INTERNAL: disableJTA(): Configure the receiver such that my external transaction controller class will
     * be ignored, and will NOT be used to populate DatabaseSession's external transaction controller class
     * at runtime.
     *
     * TopLink will NOT be configured to register for callbacks for beforeCompletion and afterCompletion.
     *
     * @see #getExternalTransactionControllerClass()
     * @see #isJTAEnabled()
     */
    @Override
    public void disableJTA() {
        this.ensureNotLoggedIn();
        this.isJTAEnabled = false;
    }

    /**
     * INTERNAL:  This method is used to unwrap the connection wrapped by
     * the application server.  TopLink needs this unwrapped connection for certain
     * database vendor specific support. (i.e. TIMESTAMPTZ,NCHAR,XMLTYPE)
     *
     * Be default we will use the connection's metadata to try to get the connection
     */
    @Override
    public java.sql.Connection unwrapConnection(java.sql.Connection connection){
        try {
            return connection.getMetaData().getConnection();
        } catch (java.sql.SQLException e){
            ((DatabaseSessionImpl)getDatabaseSession()).log(SessionLog.WARNING, SessionLog.CONNECTION, "cannot_unwrap_connection", e);
            return connection;
        }
    }

    /**
     * INTERNAL: launchContainerRunnable(Runnable runnable): Use the container library to
     * start the provided Runnable.
     *
     * Default behavior is to use Thread(runnable).start()
     *
     * @param runnable the instance of runnable to be "started"
     */
    @Override
    public void launchContainerRunnable(Runnable runnable) {
        if (getThreadPool() == null) {
            Thread thread = new Thread(runnable);
            thread.start();
        } else {
            getThreadPool().execute(runnable);
        }
    }

    /**
     * INTERNAL: Make sure that the DatabaseSession has not logged in yet.
     * Throw a ValidationException if we have.
     *
     */
    protected void ensureNotLoggedIn() {
        //RCM: Allow for a null database session
        if (getDatabaseSession() == null) {
            return;
        }
    }

    /**
     * INTERNAL: getServerLog(): Return the ServerLog for this platform
     *
     * Return the default ServerLog in the base
     *
     * @return org.eclipse.persistence.logging.SessionLog
     */
    @Override
    public org.eclipse.persistence.logging.SessionLog getServerLog() {
        return new ServerLog();
    }

    /**
     * Return the thread pool size.
     */
    @Override
    public int getThreadPoolSize() {
        return threadPoolSize;
    }

    /**
     * Set the thread pool size.
     */
    @Override
    public void setThreadPoolSize(int threadPoolSize) {
        this.threadPoolSize = threadPoolSize;
    }

    /**
     * INTERNAL: Return the thread pool, initializing if required.
     */
    public ExecutorService getThreadPool() {
        if ((threadPool == null) && (this.threadPoolSize > 0)) {
            synchronized (this) {
                if (threadPool == null) {
                    threadPool = Executors.newFixedThreadPool(getThreadPoolSize());
                }
            }
        }
        return threadPool;
    }

    /**
     * INTERNAL: Set the thread pool to use.
     */
    public void setThreadPool(ExecutorService threadPool) {
        this.threadPool = threadPool;
    }

    /**
     * INTERNAL: isCMP(): Answer true if we're in the context of CMP (i.e. the container created me)
     *
     * @return boolean
     */
    public boolean isCMP() {
        return isCMP;
    }

    /**
     * INTERNAL: setIsCMP(boolean): Define whether or not we're in the context of CMP (i.e. the container created me)
     */
    public void setIsCMP(boolean isThisCMP) {
        isCMP = isThisCMP;
    }

    /**
     * INTERNAL: shouldUseDriverManager(): Indicates whether DriverManager should be used while connecting DefaultConnector.
     *
     * @return boolean
     */
    @Override
    public boolean shouldUseDriverManager() {
        return true;
    }

    /**
     * INTERNAL:
     * A call to this method will perform a platform based check on the connection and exception
     * error code to determine if the connection is still valid or if a communication error has occurred.
     * If a communication error has occurred then the query may be retried.
     * If this platform is unable to determine if the error was communication based it will return
     * false forcing the error to be thrown to the user.
     */
    @Override
    public boolean wasFailureCommunicationBased(SQLException exception, Accessor connection, AbstractSession sessionForProfile){
        return getDatabaseSession().getPlatform().wasFailureCommunicationBased(exception, connection.getConnection(), sessionForProfile);
    }

    @Override
    public JPAClassLoaderHolder getNewTempClassLoader(PersistenceUnitInfo puInfo) {
        return new JPAClassLoaderHolder(puInfo.getNewTempClassLoader(), true);
    }

    /**
     * INTERNAL:
     * Clears statement cache of the wrapper connection.
     * Required by Oracle proxy authentication: currently connection statement cache
     * becomes invalid on switching to/from proxy session.
     * This method is called by OracleJDBC_10_1_0_2ProxyConnectionCustomizer
     * before opening proxy session and before closing it.
     */
    @Override
    public void clearStatementCache(java.sql.Connection connection) {
    }

    /**
     * INTERNAL: registerMBean(): Create and deploy the JMX MBean to provide runtime services for my
     * databaseSession.
     *
     * Default is to do nothing.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     * @see #unregisterMBean()
     */
    @Override
    public void registerMBean() {
        if (!this.isRuntimeServicesEnabled()) {
            return;
        }
        this.serverSpecificRegisterMBean();
    }

    /**
     * INTERNAL: unregisterMBean(): Unregister the JMX MBean that was providing runtime services for my
     * databaseSession.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     * @see #registerMBean()
     */
    @Override
    public void unregisterMBean() {
        if (!this.isRuntimeServicesEnabled()) {
            return;
        }
        this.serverSpecificUnregisterMBean();
    }

    /**
     * INTERNAL: perform any require shutdown tasks.
     */
    @Override
    public void shutdown() {
        unregisterMBean();
        if (this.threadPool != null) {
            this.threadPool.shutdownNow();
            this.threadPool = null;
        }
    }


    /**
     * INTERNAL: serverSpecificUnregisterMBean(): Server specific implementation of the
     * unregistration of the JMX MBean from its server.
     *
     * Default is to do nothing. This should be subclassed if required.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     */
    public void serverSpecificUnregisterMBean() { }

    /**
     * INTERNAL: serverSpecificRegisterMBean(): Server specific implementation of the
     * creation and deployment of the JMX MBean to provide runtime services for my
     * databaseSession.
     *
     * Default is to do nothing. This should be subclassed if required.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     * @see #registerMBean()
     */
    public void serverSpecificRegisterMBean() { }

    /**
     * @return Return JNDIConnector.COMPOSITE_NAME_LOOKUP.
     */
    @Override
    public int getJNDIConnectorLookupType() {
        return JNDIConnector.COMPOSITE_NAME_LOOKUP;
    }

    @Override
    public String getPartitionID() {
        return "GLOBAL";
    }

    @Override
    public boolean usesPartitions() {
        return false;
    }


}
