/*
 * 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.testing.tests.distributedservers;

import java.rmi.registry.Registry;

import java.util.Iterator;

import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.sessions.broker.SessionBroker;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Session;

/**
 * This class is used in the DistributedSession test to test the
 * Cache Synchronisation feature.  This object places a RemoteDispatcher into
 * an RMI registry and then starts a session connection.
 */
public abstract class DistributedServer {
    /** This attribute holds this threads session */
    public DatabaseSession session;

    /** This attribute holds the binding name for this server */
    public String serverName;

    /**
     * DistributedServer constructor comment.
     */
    public DistributedServer(Session testSssion) {
        super();
        if (testSssion.isSessionBroker()) {
            this.session = new SessionBroker();
            Iterator<String> enumtr = ((SessionBroker)testSssion).getSessionsByName().keySet().iterator();
            while (enumtr.hasNext()) {
                String name = enumtr.next();
                DatabaseSession newMemberSession = ((SessionBroker)testSssion).getSessionForName(name).getProject().createDatabaseSession();
                ((SessionBroker)this.session).registerSession(name, newMemberSession);
            }
        } else {
            this.session = testSssion.getProject().createDatabaseSession();
        }
        this.session.setSessionLog(testSssion.getSessionLog());
        this.session.login();
        if (testSssion.isSessionBroker()) {
            Iterator<String> enumtr = ((SessionBroker)testSssion).getSessionsByName().keySet().iterator();
            while (enumtr.hasNext()) {
                String name = enumtr.next();
                AbstractSession oldMemberSession = ((SessionBroker)testSssion).getSessionForName(name);
                AbstractSession newMemberSession = ((SessionBroker)this.session).getSessionForName(name);
                newMemberSession.getAccessor().closeConnection();
                newMemberSession.setAccessor(oldMemberSession.getAccessor());
            }
        } else {
            ((AbstractSession)this.session).getAccessor().closeConnection();
            ((AbstractSession)this.session).setAccessor(((AbstractSession)testSssion).getAccessor());
        }
    }

    /**
     * Returns the session from the distributed server
     * @return org.eclipse.persistence.sessions.DatabaseSession the Session from a particular distributed session
     */
    public org.eclipse.persistence.sessions.DatabaseSession getDistributedSession() {
        return session;
    }

    /**
     * This method returns the globally unique name of a particular server
     * @return java.lang.String the name of the server
     */
    public java.lang.String getServerName() {
        return serverName;
    }


    public boolean isObjectValid(Object object) {
        return session.getIdentityMapAccessor().isValid(object);
    }

    /**
     * This method starts the server and makes the dispatcher available
     * Creation date: (7/21/00 9:58:37 AM)
     */
    public abstract void run();

    public abstract void stopServer();

    /**
     * INTERNAL:
     * This method is used to set the globally Unique server name for the Distributed Server
     * @param newServerName java.lang.String
     */
    public void setServerName(java.lang.String newServerName) {
        serverName = newServerName;
    }

    /**
     * Removes this current server from the registry
     * Creation date: (7/21/00 10:53:37 AM)
     * @param registry java.rmi.registry.Registry
     */
    public void unbind(Registry registry) {
        try {
            registry.unbind(getServerName());
        } catch (Exception exception) {
        }
    }
}
