/*
 * Copyright (c) 2013, 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 design and implementation
package org.eclipse.persistence.sessions.coordination.jgroups;

import java.util.Map;

import org.eclipse.persistence.exceptions.RemoteCommandManagerException;
import org.eclipse.persistence.internal.sessions.coordination.RemoteConnection;
import org.eclipse.persistence.internal.sessions.coordination.broadcast.BroadcastRemoteConnection;
import org.eclipse.persistence.internal.sessions.coordination.jgroups.JGroupsRemoteConnection;
import org.eclipse.persistence.sessions.coordination.broadcast.BroadcastTransportManager;
import org.eclipse.persistence.sessions.coordination.RemoteCommandManager;
import org.jgroups.JChannel;

/**
 * <p>
 * <b>Purpose</b>: Provide a transport implementation for the Remote Command Module (RCM) that publishes
 * to a JGroup channel.
 * <p>
 * JGroups is a library for distributed communications.
 * <p>
 * If issues are encountered with the default setting try,<br>
 * -Djava.net.preferIPv4Stack=true
 *
 * @author James Sutherland
 * @since EclipseLink 2.6
 */
public class JGroupsTransportManager extends BroadcastTransportManager {
    private String configFile = "";

    /**
     * PUBLIC:
     * Creates a JGroupsTransportManager.
     */
    public JGroupsTransportManager() {
    }

    /**
     * PUBLIC:
     * Creates a JGroupsTransportManager.
     */
    public JGroupsTransportManager(RemoteCommandManager rcm) {
        super(rcm);
    }

    /**
     * INTERNAL:
     * This method creates JGroupsRemoteConnection to be used by this TransportManager.
     * It uses a JGroups JChannel using the RCM channel name and specified (or defaulted) config file.
     * Channel is set to not receive own messages.
     */
    protected BroadcastRemoteConnection createConnection(boolean isLocalConnectionBeingCreated) throws RemoteCommandManagerException {
        try {
            JChannel channel;
            if (configFile != null && !configFile.isEmpty()) {
                channel = new JChannel(configFile);
            } else {
                channel = new JChannel();
            }
            channel.connect(this.rcm.getChannel());
            channel.setDiscardOwnMessages(true);
            return new JGroupsRemoteConnection(this.rcm, channel, isLocalConnectionBeingCreated);
        } catch (Exception ex) {
            throw RemoteCommandManagerException.errorCreatingJGroupsConnection(this.configFile, ex);
        }
    }

    /**
     * INTERNAL:
     * JGroups does not require a DiscoveryManager, therefore
     * this method is called during RCM initialization to create all the necessary connections.
     */
    @Override
    public void createConnections() {
        createLocalConnection();
        createExternalConnection();
    }

    /**
     * INTERNAL:
     * JGroups only has a single connection.
     * Verify there are no external connections, use the local connection as the external connection.
     */
    public void createExternalConnection() {
        synchronized (this.connectionsToExternalServices) {
            if (this.connectionsToExternalServices.isEmpty()) {
                try {
                    this.connectionsToExternalServices.put(this.rcm.getServiceId().getId(), this.localConnection);
                } catch (RemoteCommandManagerException rcmException) {
                    // to recover handle RemoteCommandManagerException.ERROR_CREATING_JMS_CONNECTION:
                    // after changing something (for instance config)
                    // call createExternalConnection method again.
                    rcm.handleException(rcmException);
                }
            }
        }
    }

    /**
     * INTERNAL:
     * JGroups only requires a single connection.
     * In case the local connection doesn't exist, this method creates it.
     */
    @Override
    public synchronized void createLocalConnection() {
        if (this.localConnection == null) {
            try {
                this.localConnection = createConnection(true);
            } catch (RemoteCommandManagerException rcmException) {
                // to recover handle RemoteCommandManagerException.ERROR_CREATING_LOCAL_JMS_CONNECTION:
                // after changing something (for instance jmsHostUrl)
                // call createLocalConnection method again.
                rcm.handleException(rcmException);
            }
        }
    }


    /**
     * INTERNAL:
     * In case there's no external connection attempts to create one.
     * Returns external connections (only a single connection for JGroups).
     */
    @Override
    public Map<String, RemoteConnection> getConnectionsToExternalServicesForCommandPropagation() {
        if (getConnectionsToExternalServices().isEmpty() && !this.rcm.isStopped()) {
            createExternalConnection();
        }
        return super.getConnectionsToExternalServicesForCommandPropagation();
    }

    /**
     * INTERNAL:
     * No-op, as the local connection does not need to be removed as JGroups manages registration.
     */
    @Override
    public void removeLocalConnection() {}

    /**
     * PUBLIC:
     * Return the JGroups config xml file name.
     */
    public String getConfigFile() {
        return configFile;
    }

    /**
     * PUBLIC:
     * Set the JGroups config xml file name.
     */
    @Deprecated
    public void setConfigFile(String configFile) {
        this.configFile = configFile;
    }
     
    @Override
    public void setConfig(String config) {
        configFile = config;
    }
}
