/*
 * 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.remote;

import java.util.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.sessions.remote.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sessions.Login;
import org.eclipse.persistence.sessions.SessionProfiler;
import org.eclipse.persistence.internal.queries.*;
import org.eclipse.persistence.internal.identitymaps.*;
import org.eclipse.persistence.internal.sessions.*;

/**
 * <b>Purpose</b>: Super class to all remote client session's.
 */
public abstract class DistributedSession extends DatabaseSessionImpl {
    /** Connection to remote persistence service. */
    protected transient RemoteConnection remoteConnection;
    /** Cache if default classes have been read from server. */
    protected boolean hasDefaultReadOnlyClasses;
    /** Define if meta-data is initialized locally, or serialized from the server. */
    protected boolean isMetadataRemote = true;

    /**
     * INTERNAL:
     * Create a blank session, used for proxy session.
     */
    protected DistributedSession(int nothing) {
    }

    /**
     * PUBLIC:
     * Creates a DistributedSession.
     * @param remoteConnection remote session requires a remote connection. This must be accessed remotely from the client through RMI or CORBA.
     */
    protected DistributedSession(RemoteConnection remoteConnection) {
        this.remoteConnection = remoteConnection;
        this.remoteConnection.initialize(this);
        this.project = new org.eclipse.persistence.sessions.Project();
    }

    /**
     * PUBLIC:
     * Return a unit of work for this session.
     * The unit of work is an object level transaction that allows
     * a group of changes to be applied as a unit.
     *
     * @see UnitOfWorkImpl
     */
    @Override
    public abstract UnitOfWorkImpl acquireUnitOfWork();

    /**
     * PUBLIC:
     * Start a transaction on the server.
     * A unit of work should normally be used instead of transactions for the remote session.
     */
    @Override
    public void beginTransaction() {
        // Acquire the mutex so session knows it is in a transaction.
        getTransactionMutex().acquire();
        startOperationProfile(SessionProfiler.Remote, null, SessionProfiler.ALL);
        getRemoteConnection().beginTransaction();
        endOperationProfile(SessionProfiler.Remote, null, SessionProfiler.ALL);
    }

    /**
     * PUBLIC:
     * Commit a transaction on the server.
     * A unit of work should normally be used instead of transactions for the remote session.
     */
    @Override
    public void commitTransaction() {
        startOperationProfile(SessionProfiler.Remote, null, SessionProfiler.ALL);
        getRemoteConnection().commitTransaction();
        endOperationProfile(SessionProfiler.Remote, null, SessionProfiler.ALL);
        getTransactionMutex().release();
    }

    /**
     * INTERNAL:
     * Return remote cursor stream.
     */
    public RemoteCursoredStream cursorSelectObjects(CursoredStreamPolicy policy) {
        return getRemoteConnection().cursorSelectObjects(policy, this);
    }

    /**
     * INTERNAL:
     * Return remote scrollable cursor
     */
    public RemoteScrollableCursor cursorSelectObjects(ScrollableCursorPolicy policy) {
        return getRemoteConnection().cursorSelectObjects(policy, this);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     * The named query can be defined on the remote session or the server-side session.
     *
     * @see #addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName) throws DatabaseException {
        return executeQuery(queryName, new Vector(1));
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     * The class is the descriptor in which the query was pre-defined.
     * The query is executed on the server-side session.
     *
     * @see DescriptorQueryManager#addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Class<?> domainClass) throws DatabaseException {
        return executeQuery(queryName, domainClass, new Vector(1));
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     * The class is the descriptor in which the query was pre-defined.
     *
     * @see DescriptorQueryManager#addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Class<?> domainClass, Vector argumentValues) throws DatabaseException {
        startOperationProfile(SessionProfiler.Remote, null, SessionProfiler.ALL);
        Transporter transporter = getRemoteConnection().remoteExecuteNamedQuery(queryName, domainClass, argumentValues);
        endOperationProfile(SessionProfiler.Remote, null, SessionProfiler.ALL);
        transporter.getQuery().setSession(this);
        return transporter.getQuery().extractRemoteResult(transporter);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     *
     * @see #addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Vector argumentValues) throws DatabaseException {
        if (containsQuery(queryName)) {
            return super.executeQuery(queryName, argumentValues);
        }
        return executeQuery(queryName, null, argumentValues);
    }

    /**
     * Execute the database query.
     */
    @Override
    public abstract Object executeQuery(DatabaseQuery query);

    /**
     * INTERNAL:
     * Execute the database query.
     */
    @Override
    public Object executeQuery(DatabaseQuery query, AbstractRecord row) {
        query.setTranslationRow(row);
        return executeQuery(query);
    }

    /**
     * INTERNAL:
     * CR#2751
     * Returns the set of read-only classes for the receiver.  These class come from the
     * Remote connection
     * @return A Vector containing the Java Classes that are currently read-only.
     */
    @Override
    public Vector getDefaultReadOnlyClasses() {
        if (this.isMetadataRemote && !this.hasDefaultReadOnlyClasses) {
            getProject().setDefaultReadOnlyClasses(getRemoteConnection().getDefaultReadOnlyClasses());
            this.hasDefaultReadOnlyClasses = true;
        }
        return super.getDefaultReadOnlyClasses();
    }

    /**
     * INTERNAL:
     * Return the table descriptor specified for the class.
     */
    @Override
    public ClassDescriptor getDescriptor(Class<?> domainClass) {
        ClassDescriptor descriptor = getDescriptors().get(domainClass);

        // If the descriptor is null then this means that descriptor must now be read from the server.
        if (descriptor == null) {
            if (!this.isMetadataRemote) {
                return super.getDescriptor(domainClass);
            }
            startOperationProfile(SessionProfiler.RemoteMetadata, null, SessionProfiler.ALL);
            descriptor = getRemoteConnection().getDescriptor(domainClass);
            endOperationProfile(SessionProfiler.RemoteMetadata, null, SessionProfiler.ALL);
            if (descriptor == null) {
                return super.getDescriptor(domainClass);
            }
            getDescriptors().put(domainClass, descriptor);
            String alias = descriptor.getAlias();
            if (alias != null) {
                getProject().addAlias(alias, descriptor);
            }
            descriptor.remoteInitialization(this);
        }

        return descriptor;
    }

    /**
     * INTERNAL:
     * Return the table descriptor specified for the class.
     */
    @Override
    public ClassDescriptor getDescriptorForAlias(String alias) {
        ClassDescriptor descriptor = super.getDescriptorForAlias(alias);

        // If the descriptor is null then this means that descriptor must now be read from the server.
        if (descriptor == null) {
            if (!this.isMetadataRemote) {
                return null;
            }
            startOperationProfile(SessionProfiler.RemoteMetadata, null, SessionProfiler.ALL);
            descriptor = getRemoteConnection().getDescriptorForAlias(alias);
            endOperationProfile(SessionProfiler.RemoteMetadata, null, SessionProfiler.ALL);
            if (descriptor == null) {
                return null;
            }
            getDescriptors().put(descriptor.getJavaClass(), descriptor);
            getProject().addAlias(alias, descriptor);
            descriptor.remoteInitialization(this);
        }

        return descriptor;
    }

    /**
     * INTERNAL:
     * Return the descriptor.
     */
    public ClassDescriptor getDescriptorCorrespondingTo(ClassDescriptor descriptor) {
        return getDescriptors().get(descriptor.getJavaClass());
    }

    /**
     * INTERNAL:
     * Return the corresponding objects from the remote session for the objects read from the server.
     */
    public abstract Object getObjectCorrespondingTo(Object serverSideDomainObject, Map<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> processedObjects, ObjectLevelReadQuery query);

    /**
     * INTERNAL:
     * Return the corresponding objects from the remote session for the objects read from the server.
     */
    public abstract Object getObjectsCorrespondingToAll(Object serverSideDomainObjects, Map<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> processedObjects, ObjectLevelReadQuery query, ContainerPolicy containerPolicy);

    /**
     * INTERNAL:
     * Return the remote connection.
     */
    public RemoteConnection getRemoteConnection() {
        return remoteConnection;
    }

    /**
     * INTERNAL:
     * Checks if the descriptor exists or not.
     */
    public boolean hasCorrespondingDescriptor(ClassDescriptor descriptor) {
        return getDescriptors().containsKey(descriptor.getJavaClass());
    }

    /**
     * INTERNAL:
     * Set up the IdentityMapManager.  Overrides the default IdentityMapManager
     */
    @Override
    public void initializeIdentityMapAccessor() {
        this.identityMapAccessor = new DistributedSessionIdentityMapAccessor(this, new IdentityMapManager(this));
    }

    /**
     * INTERNAL:
     * This will instantiate value holder on the server.
     */
    public abstract Object instantiateRemoteValueHolderOnServer(RemoteValueHolder remoteValueHolder);

    /**
     * PUBLIC:
     * Return if this session is connected to the server.
     */
    @Override
    public boolean isConnected() {
        if (getRemoteConnection() == null) {
            return false;
        }

        return getRemoteConnection().isConnected();
    }

    /**
     * INTERNAL:
     * Return if this session is a distributed session.
     */
    @Override
    public boolean isDistributedSession() {
        return true;
    }

    /**
     * INTERNAL:
     * Return if this session is a remote session.
     */
    @Override
    public boolean isRemoteSession() {
        return false;
    }

    /**
     * INTERNAL:
     * You cannot add descriptors to a remote session. This is a internal method used by TopLink
     */
    public void privilegedAddDescriptor(ClassDescriptor descriptor) {
        getDescriptors().put(descriptor.getJavaClass(), descriptor);
    }

    /**
     * PUBLIC:
     * Rollback a transaction on the server.
     * A unit of work should normally be used instead of transactions for the remote session.
     */
    @Override
    public void rollbackTransaction() {
        startOperationProfile(SessionProfiler.Remote, null, SessionProfiler.ALL);
        getRemoteConnection().rollbackTransaction();
        endOperationProfile(SessionProfiler.Remote, null, SessionProfiler.ALL);
        getTransactionMutex().release();
    }

    /**
     * INTERNAL:
     * Set the remote connection.
     */
    public void setRemoteConnection(RemoteConnection remoteConnection) {
        this.remoteConnection = remoteConnection;
    }

    /**
     * PUBLIC:
     * Avoid printing the accessor and platform.
     */
    @Override
    public String toString() {
        return Helper.getShortClassName(getClass()) + "()";
    }

    /**
     * PUBLIC:
     * Logout the session, close the remote connection and release the hold resources
     */
    @Override
    public void logout() {
        //CR3854: logging out of DistributedSession is not releasing remote resources.
        //The remote connection remove() call should  release the resource, like the stateful
        //session been, which the connection holds on.
        this.remoteConnection.release();
    }

    /**
     * ADVANCED:
     * Return if the descriptors and meta-data should be serialized from the server,
     * or if they will be provided locally.
     */
    public boolean isMetadataRemote() {
        return isMetadataRemote;
    }

    /**
     * ADVANCED:
     * Set if the descriptors and meta-data should be serialized from the server,
     * or if they will be provided locally.
     */
    public void setIsMetadataRemote(boolean isMetadataRemote) {
        this.isMetadataRemote = isMetadataRemote;
    }

    /**
     * INTERNAL:
     * Connect not required.
     */
    @Override
    public void connect() throws DatabaseException {
        this.remoteConnection.initialize(this);
    }

    /**
     * INTERNAL:
     * Disconnect not required.
     */
    @Override
    public void disconnect() throws DatabaseException {
        getSequencingHome().onDisconnect();
    }

    /**
     * PUBLIC:
     * Connect to the database using the predefined login.
     * During connection, attempt to auto detect the required database platform.
     * This method can be used in systems where for ease of use developers have
     * EclipseLink autodetect the platform.
     * To be safe, however, the platform should be configured directly.
     * The login must have been assigned when or after creating the session.
     */
    @Override
    public void loginAndDetectDatasource() throws DatabaseException {
        preConnectDatasource();
        connect();
        Login login = this.remoteConnection.getLogin();
        setLogin(login);
        postConnectDatasource();
    }

    /**
     * PUBLIC:
     * Connect to the database using the predefined login.
     * Obtain the login from the server, as it may have configuration initialized from the database meta-data.
     */
    @Override
    public void login() throws DatabaseException {
        preConnectDatasource();
        connect();
        Login login = this.remoteConnection.getLogin();
        setLogin(login);
        postConnectDatasource();
    }
}
