/*
 * 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
package org.eclipse.persistence.sessions.coordination.corba;

import org.eclipse.persistence.exceptions.RemoteCommandManagerException;
import org.eclipse.persistence.internal.helper.SerializationHelper;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.sessions.coordination.RemoteConnection;
import org.eclipse.persistence.internal.sessions.coordination.corba.*;
import org.eclipse.persistence.sessions.coordination.Command;
import org.eclipse.persistence.sessions.coordination.RemoteCommandManager;
import org.eclipse.persistence.sessions.coordination.ServiceId;
import org.eclipse.persistence.sessions.coordination.TransportManager;
import java.io.IOException;
import java.net.InetAddress;
import javax.naming.Context;

public abstract class CORBATransportManager extends TransportManager {

    public CORBATransportManager(RemoteCommandManager rcm) {
        this.rcm = rcm;
        this.initialize();
    }

    /**
     * INTERNAL:
     * Initialize default properties for RMI.
     */
    @Override
    public void initialize() {
        super.initialize();
        if (rcm.getServiceId().getURL() == null) {
            rcm.getServiceId().setURL(getDefaultLocalUrl());
        }

        namingServiceType = TransportManager.JNDI_NAMING_SERVICE;
        setInitialContextFactoryName(getDefaultInitialContextFactoryName());
    }

    /**
     * ADVANCED:
     * Return the default local URL for JNDI lookups
     */
    public String getDefaultLocalUrl() {
        try {
            // Look up the local host name and paste it in a default URL
            String localHost = InetAddress.getLocalHost().getHostName();
            return "iiop://" + localHost + ":" + DEFAULT_URL_PORT;
        } catch (IOException exception) {
            throw RemoteCommandManagerException.errorGettingHostName(exception);
        }
    }

    /**
     * ADVANCED:
     * Remove the local connection from remote accesses.  The implementation removes the local connection from JNDI or RMI registry 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.
     */
    @Override
    public void removeLocalConnection() {
        String unbindName = null;
        try {
            if (namingServiceType == JNDI_NAMING_SERVICE) {
                unbindName = rcm.getServiceId().getId();
                getContext(getLocalContextProperties()).unbind(unbindName);
            } else {
                return;
            }
        } catch (Exception exception) {
            rcm.handleException(RemoteCommandManagerException.errorUnbindingLocalConnection(unbindName, exception));
        }
        localConnection = null;
    }

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

    /**
     * PUBLIC:
     * Return the default initial context factory name for a specific CORBA orb.
     */
    public abstract String getDefaultInitialContextFactoryName();

    /**
     * PUBLIC:
     * Narrow the object using the specific generated CORBA Helper class and cast it to a <code>CORBAConnection</code>.
     */
    public abstract CORBAConnection narrow(org.omg.CORBA.Object object);

    /**
     * PUBLIC:
     * Return a new instance of the specific CORBA implementation that implements <code>CORBAConnection</code> interface.
     */
    public abstract CORBAConnection buildCORBAConnection();

    /**
     * INTERNAL:
     * Create and return a wrapper of  a CORBA remote connection to the specified service
     */
    @Override
    public RemoteConnection createConnection(ServiceId connectionServiceId) {
        RemoteConnection connection = null;

        Object[] args = { connectionServiceId.getId(), connectionServiceId.getURL() };
        rcm.logDebug("looking_up_remote_conn_in_jndi", args);
        try {
            Context context = getRemoteHostContext(connectionServiceId.getURL());

            // look up the distributed connection from JNDI
            CORBAConnection connectionImpl = narrow((org.omg.CORBA.Object)context.lookup(connectionServiceId.getId()));

            // create the wrapper of  the distributed connection
            connection = new CORBARemoteCommandConnection(connectionImpl);
            connection.setServiceId(connectionServiceId);

        } catch (Exception e) {
            rcm.handleException(RemoteCommandManagerException.errorLookingUpRemoteConnection(connectionServiceId.getId(), connectionServiceId.getURL(), e));
        }
        return connection;
    }

    /**
     * INTERNAL:
     * Helper method that processes a byte[] command.  This method is called bye the CORBA implementation class
     * that implements the method byte[]  executeCommand(byte[] command)
     *
     */
    public static byte[] processCommand(byte[] command, RemoteCommandManager rcm) {
        try {
            if (rcm.getSerializer() != null) {
                rcm.processCommandFromRemoteConnection(command);
            } else {
                // deserialize byte [] to Command object
                Command deserializedCmd = (Command)SerializationHelper.deserialize(command);
                rcm.processCommandFromRemoteConnection(deserializedCmd);
            }
        } catch (Exception e) {
            // Log the problem encountered during deserialization or rcm processing command
            Object[] args = { Helper.getShortClassName(command), Helper.printStackTraceToString(e) };
            rcm.logWarning("error_executing_remote_command", args);

            // Return the byte[] of exception String in case the exception doesn't exist on the other side
            return e.toString().getBytes();
        }

        // Success - return null
        return null;
    }

    /**
     * INTERNAL:
     * Create the local command connection for this transport in a naming service and
     * return it.
     */
    @Override
    public void createLocalConnection() {
        // Register the remote connection in JNDI naming service
        CORBAConnection connectionImpl = buildCORBAConnection();

        Object[] args = { rcm.getServiceId().getId() };
        rcm.logDebug("register_local_connection_in_jndi", args);

        try {
            getRemoteHostContext(rcm.getUrl()).rebind(rcm.getServiceId().getId(), connectionImpl);
        } catch (Exception exception) {
            rcm.handleException(RemoteCommandManagerException.errorBindingConnection(rcm.getServiceId().toString(), exception));
            return;
        }

        localConnection = new CORBARemoteCommandConnection(connectionImpl);
        localConnection.setServiceId(rcm.getServiceId());
    }
}
