/*
 * 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
//     17/10/2008-1.1  Michael O'Brien
//       - 251005: The default JNDI InitialContextFactory is modified from
//       OC4J: oracle.j2ee.rmi.RMIInitialContextFactory to
//       WebLogic: weblogic.jndi.WLInitialContextFactory
package org.eclipse.persistence.sessions.coordination;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;

import javax.naming.Context;
import javax.naming.NamingException;

import org.eclipse.persistence.exceptions.CommunicationException;
import org.eclipse.persistence.exceptions.RemoteCommandManagerException;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.SecurableObjectHolder;
import org.eclipse.persistence.internal.sessions.coordination.ConnectToHostCommand;
import org.eclipse.persistence.internal.sessions.coordination.RemoteConnection;

/**
 * <p>
 * <b>Purpose</b>: Provide an abstract class that offers a common API to handling
 * remote command connections.
 * </p><p>
 * <b>Description</b>: This class manages the remote connections to other RCM service
 * instances and posts the local connection to this service instance in a name
 * service so that other RCM service instances can connect to it.
 * </p>
 * @author Steven Vo
 * @since OracleAS TopLink 10<i>g</i> (9.0.4)
 */
public abstract class TransportManager {

    /** The remote command connection to this transport */
    protected RemoteConnection localConnection;

    /** The RCM that manages this transport */
    protected RemoteCommandManager rcm;

    /** The type of naming service used to look up other connections */
    protected int namingServiceType;

    /** Properties to obtain the context used for local JNDI access */
    protected Hashtable localContextProperties;

    /** Properties to obtain the context used for remote JNDI access */
    protected Hashtable remoteContextProperties;

    /** Determines whether a connection should be discarded if an error occurs on it */
    protected boolean shouldRemoveConnectionOnError;

    /** Connections to other services */
    protected Hashtable<String, RemoteConnection> connectionsToExternalServices;

    /** Security util that is used to decrypt and encrypt password */
    protected SecurableObjectHolder securableObjectHolder;

    public static final boolean DEFAULT_REMOVE_CONNECTION_ON_ERROR_MODE = true;

    /** Valid values for naming service type */
    public static final int JNDI_NAMING_SERVICE = 0;
    public static final int REGISTRY_NAMING_SERVICE = 1;

    /** Defaults for RMI applications */
    public static final String DEFAULT_URL_PROTOCOL = "rmi";
    public static final String DEFAULT_IIOP_URL_PROTOCOL = "corbaname";
    public static final String DEFAULT_URL_PORT = "23791";
    public static final String DEFAULT_IIOP_URL_PORT = "5555#";
    public static final int DEFAULT_NAMING_SERVICE = JNDI_NAMING_SERVICE;

    /** Default JNDI properties for remote access */
    public static final String DEFAULT_CONTEXT_FACTORY = "weblogic.jndi.WLInitialContextFactory";
    public static final String DEFAULT_DEDICATED_CONNECTION_KEY = "dedicated.connection";
    public static final String DEFAULT_DEDICATED_CONNECTION_VALUE = "true";
    public static final String DEFAULT_USER_NAME = "admin";

    /**
     * INTERNAL:
     * Return a remote connection to the specified service
     */
    public abstract RemoteConnection createConnection(ServiceId serviceId);

    /**
     * INTERNAL:
     * Does nothing by default. In case TransportManager doesn't use DiscoveryManager
     * (createDiscoveryManager method retuns null)
     * this method called during RCM initialization to create all the necessary connections.
     * TransportManager ancestors that override createDiscoveryManager method to return null
     * must override this method, too.
     */
    public void createConnections() {
    }

    /**
     * INTERNAL:
     * This method is called by the remote command manager when this service should
     * connect back ('handshake') to the service from which this remote connection came.
     */
    public void connectBackToRemote(RemoteConnection connection) throws Exception {
        ConnectToHostCommand command = new ConnectToHostCommand();
        command.setServiceId(rcm.getServiceId());
        connection.executeCommand(command);
    }

    /**
     * INTERNAL:
     * Return a remote connection to this service
     */
    public RemoteConnection getConnectionToLocalHost() {
        return localConnection;
    }

    /**
     * INTERNAL:
     * Put the remote connection to local host in naming service and return the  of the created remote connection
     */
    public abstract void createLocalConnection();

    /**
     * PUBLIC:
     * Return the type of naming service used to look up remote connections to other
     * service instances.
     *
     * @return The type of naming service used.
     */
    public int getNamingServiceType() {
        return namingServiceType;
    }

    /**
     * ADVANCED:
     * Set the type of naming service used to look up remote connections to other
     * service instances. The service type must be one of JNDI_NAMING_SERVICE or
     * REGISTRY_NAMING_SERVICE.
     */
    public void setNamingServiceType(int serviceType) {
        namingServiceType = serviceType;
    }

    /**
     * PUBLIC:
     * Return the user name used as the value to the SECURITY_PRINCIPAL key in the
     * cached context properties.
     */
    public String getUserName() {
        return (String)getRemoteContextProperties().get(Context.SECURITY_PRINCIPAL);
    }

    /**
     * ADVANCED:
     * Set the user name used as the value to the SECURITY_PRINCIPAL key in the
     * cached context properties.
     */
    public void setUserName(String userName) {
        getRemoteContextProperties().put(Context.SECURITY_PRINCIPAL, userName);
    }

    /**
     * PUBLIC:
     * Return the password used as the value to the SECURITY_CREDENTIALS key in
     * the cached context properties.
     */
    public String getPassword() {
        return decrypt(getEncryptedPassword());
    }

    /**
     * PUBLIC:
     * Return the encrypted (assumed) password used as the value to the
     * SECURITY_CREDENTIALS key in the cached context properties.
     */
    public String getEncryptedPassword() {
        return (String) getRemoteContextProperties().get(Context.SECURITY_CREDENTIALS);
    }

    /**
     * ADVANCED:
     * Set the password used as the value to the SECURITY_CREDENTIALS key in the
     * cached context properties.
     */
    public void setPassword(String password) {
        if (password != null) {
            getRemoteContextProperties().put(Context.SECURITY_CREDENTIALS, encrypt(password));
        }
    }

    /**
     * ADVANCED:
     * Set the encrypted password used as the value to the SECURITY_CREDENTIALS key in the
     * cached context properties.
     */
    public void setEncryptedPassword(String encryptedPassword) {
        getRemoteContextProperties().put(Context.SECURITY_CREDENTIALS, encryptedPassword);
    }

    /**
     * PUBLIC:
     * Return the context factory name used as the value to the INITIAL_CONTEXT_FACTORY
     * key in the cached context properties.
     */
    public String getInitialContextFactoryName() {
        return (String)getRemoteContextProperties().get(Context.INITIAL_CONTEXT_FACTORY);
    }

    /**
     * ADVANCED:
     * Set the context factory name used as the value to the INITIAL_CONTEXT_FACTORY
     * key in the cached context properties.
     */
    public void setInitialContextFactoryName(String contextFactoryName) {
        getRemoteContextProperties().put(Context.INITIAL_CONTEXT_FACTORY, contextFactoryName);
    }

    /**
     * INTERNAL:
     * Helper method to get a naming context.
     */
    public Context getContext(Hashtable contextProperties) {
        try {
            return new javax.naming.InitialContext(contextProperties);
        } catch (NamingException exception) {
            RemoteCommandManagerException rcmException = RemoteCommandManagerException.errorObtainingContext(exception);
            rcm.handleException(RemoteCommandManagerException.errorObtainingContext(exception));
            throw rcmException;
        }
    }

    /**
     * ADVANCED:
     * Return the cached properties that will be used to create the initial context
     * when doing remote JNDI lookups.
     */
    public Hashtable getRemoteContextProperties() {
        return remoteContextProperties;
    }

    /**
     * ADVANCED:
     * Set the cached properties that will be used to create the initial context
     * when doing remote JNDI lookups.
     */
    public void setRemoteContextProperties(Hashtable properties) {
        remoteContextProperties = properties;
    }

    /**
     * ADVANCED:
     * Return the properties that will be used to create the initial context
     * for local JNDI access.
     */
    public Hashtable getLocalContextProperties() {
        if (localContextProperties == null) {
            localContextProperties = new Hashtable();
        }
        return localContextProperties;
    }

    /**
     * ADVANCED:
     * Set the properties that will be used to create the initial context
     * for local JNDI access.
     */
    public void setLocalContextProperties(Hashtable properties) {
        localContextProperties = properties;
    }

    /**
     * INTERNAL:
     */
    public RemoteCommandManager getRemoteCommandManager() {
        return rcm;
    }

    /**
     * INTERNAL:
     */
    public void setRemoteCommandManager(RemoteCommandManager rcm) {
        this.rcm = rcm;
    }

    /**
     * INTERNAL:
     * Add a remote Connection to a remote service.
     */
    public void addConnectionToExternalService(RemoteConnection connection) {
        if (connection == null) {
            return;
        }
        try {
            connectBackToRemote(connection);
            connectionsToExternalServices.put(connection.getServiceId().getId(), connection);
            Object[] args = { connection.getServiceId() };
            rcm.logDebug("received_connection_from", args);
        } catch (Exception exception) {
            try {
                rcm.handleException(CommunicationException.errorSendingConnectionService(connection.toString(), exception));
            } catch (RuntimeException reThrownException) {
                Object[] args = { connection.getServiceId(), reThrownException };
                rcm.logWarning("problem_adding_connection", args);
                if (!shouldRemoveConnectionOnError) {
                    throw reThrownException;
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Remove a remote connection from the list of connections to receive remote commands.
     */
    public void removeConnectionToExternalService(RemoteConnection connection) {
        synchronized (this) {
            connectionsToExternalServices.remove(connection.getServiceId().getId());
            connection.close();
        }
    }

    /**
     * INTERNAL:
     * Remove all remote connections from the list.
     */
    public void removeAllConnectionsToExternalServices() {
        synchronized (this) {
            Enumeration connections = connectionsToExternalServices.elements();
            connectionsToExternalServices = new Hashtable(3);

            while (connections.hasMoreElements()) {
                ((RemoteConnection)connections.nextElement()).close();
            }
        }
    }

    /**
     * INTERNAL:
     */
    public Map<String, RemoteConnection> getConnectionsToExternalServices() {
        return connectionsToExternalServices;
    }

    /**
     * INTERNAL:
     * Returns clone of the original map.
     */
    public Map<String, RemoteConnection> getConnectionsToExternalServicesForCommandPropagation() {
        return (Map<String, RemoteConnection>) connectionsToExternalServices.clone();
    }

    /**
     * PUBLIC:
     * Set whether connections to remote services should be disconnected when an
     * error occurs.
     */
    public void setShouldRemoveConnectionOnError(boolean shouldRemoveConnectionOnError) {
        this.shouldRemoveConnectionOnError = shouldRemoveConnectionOnError;
    }

    /**
     * PUBLIC:
     * Return whether connections to remote services should be disconnected when an
     * error occurs.
     */
    public boolean shouldRemoveConnectionOnError() {
        return shouldRemoveConnectionOnError;
    }

    /**
     * INTERNAL SECURITY:
     * Set encryption class that will be loaded by the SecurableObjectHolder
     */
    public void setEncryptionClassName(String encryptionClassName) {
        SecurableObjectHolder oldHolder = securableObjectHolder;

        // re-initialize encryption mechanism
        securableObjectHolder = new SecurableObjectHolder();
        securableObjectHolder.setEncryptionClassName(encryptionClassName);

        // re-encrypt password
        if (hasPassword()) {
            setPassword(oldHolder.getSecurableObject().decryptPassword(getEncryptedPassword()));
        }
    }

    /**
     * INTERNAL:
     * @return true if a non null password has been set.
     */
    protected boolean hasPassword() {
        return getRemoteContextProperties().containsKey(Context.SECURITY_CREDENTIALS) && getRemoteContextProperties().get(Context.SECURITY_CREDENTIALS) != null;
    }

    /**
     * INTERNAL:
     * Initialize default properties.
     */
    public void initialize() {
        this.shouldRemoveConnectionOnError = DEFAULT_REMOVE_CONNECTION_ON_ERROR_MODE;
        this.connectionsToExternalServices = new Hashtable(2);

        remoteContextProperties = new Hashtable();
        // Factory is not require inside the server, do not default.
        //remoteContextProperties.put(Context.INITIAL_CONTEXT_FACTORY, DEFAULT_CONTEXT_FACTORY);
        remoteContextProperties.put(DEFAULT_DEDICATED_CONNECTION_KEY, DEFAULT_DEDICATED_CONNECTION_VALUE);
        // User/password are not required inside the server, do not default.
        //remoteContextProperties.put(Context.SECURITY_PRINCIPAL, DEFAULT_USER_NAME);

        this.securableObjectHolder = new SecurableObjectHolder();
    }

    /**
     * INTERNAL:
     * Security method.
     */
    protected String encrypt(String pwd) {
        return securableObjectHolder.getSecurableObject().encryptPassword(pwd);
    }

    /**
     * INTERNAL:
     * Security method called by the children classes
     */
    protected String decrypt(String encryptedPwd) {
        return securableObjectHolder.getSecurableObject().decryptPassword(encryptedPwd);
    }

    /**
     * INTERNAL:
     * Return the context used for looking up in the JNDI space of the specified remote URL.
     */
    public Context getRemoteHostContext(String remoteHostURL) {
        Hashtable remoteProperties = (Hashtable)getRemoteContextProperties().clone();
        // Host is only required if JMS connection factory is not accessible from local JNDI.
        if (remoteHostURL != null) {
            remoteProperties.put(Context.PROVIDER_URL, remoteHostURL);
        }
        Object[] args = { remoteProperties };
        rcm.logDebug("context_props_for_remote_lookup", args);

        if (hasPassword()) {
            // decrypt password just before looking up context. Calling
            // getPassword() will decrypt it.
            remoteProperties.put(Context.SECURITY_CREDENTIALS, getPassword());
        }

        return getContext(remoteProperties);
    }

    /**
     * ADVANCED:
     * Factory of new DiscoveryManager for different transports.  The RemoteCommandManger uses this method to create its DicscoveryManager.
     * Sub-class of TransportManager should return special discovery if required.  The default is discovery type is DiscoveryManager;
     * If this method returns null then during initialization RemoteCommandManager
     * calls createConnections method.
     */
    public DiscoveryManager createDiscoveryManager() {
        return new DiscoveryManager(rcm);
    }

    /**
     * INTERNAL:
     * Remove all remote connections for its list and the local connection from JNDI or JMS Subsriber
     */
    public void discardConnections() {
        removeLocalConnection();
        removeAllConnectionsToExternalServices();
    }

    /**
     * ADVANCED:
     * Remove the local connection from remote accesses.  The implementation should set remove the local connection from JNDI or JMS and set it to null.
     * This method is invoked internally by TopLink when the RCM is shutdown and should not be invoked by user's application.
     */
    public abstract void removeLocalConnection();

    /**
     * Generic API to allow config to be set.
     */
    public void setConfig(String config) {
    }

    /**
     * INTERNAL:
     * Creates a new instance of {@code org.eclipse.persistence.sessions.coordination.rmi.RMITransportManager} class.
     * @param rcm cache coordination manager
     * @return new instance of RMI transport manager implementation
     */
    public static TransportManager newSunCORBATransportManager(final RemoteCommandManager rcm) {
        try {
            return (TransportManager) PrivilegedAccessHelper.invokeConstructor(
                    PrivilegedAccessHelper.getConstructorFor(
                            Class.forName("org.eclipse.persistence.sessions.coordination.corba.sun.SunCORBATransportManager"),
                            new Class<?>[] { RemoteCommandManager.class }, false),
                    new Object[] { rcm });
        } catch (ReflectiveOperationException e) {
            throw RemoteCommandManagerException.errorInitCorba("org.eclipse.persistence.sessions.coordination.corba.sun.SunCORBATransportManager", e);
        }
    }

}
