/*
 * 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";

    /**
     * Default constructor.
     */
    protected TransportManager() {
    }

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

}
