/*
 * Copyright (c) 1998, 2019 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.internal.sessions.remote;

import java.rmi.server.ObjID;
import java.io.*;
import org.eclipse.persistence.sessions.remote.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.indirection.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.indirection.*;
import org.eclipse.persistence.mappings.*;

/**
 * Remote value holders can be invoked locally and remotely.
 * In both situations the associated indirect object is invoked.
 */
public class RemoteValueHolder extends DatabaseValueHolder implements Externalizable {
    // This is a unique id for remote value holder.
    protected ObjID id;

    // Primary key row for target object.
    protected Object targetObjectPrimaryKeys;
    protected transient DatabaseMapping mapping;
    protected transient ObjectLevelReadQuery query;

    // The server side original value holder.
    protected transient ValueHolderInterface<Object> wrappedServerValueHolder;

    // point back to the object holding the remote value holder;
    // for the moment, used only by TransparentIndirection
    protected transient Object serverIndirectionObject;

    public RemoteValueHolder() {
        // This assigns unique id to the remote value holder when it is created.
        this.id = new ObjID();
    }

    public RemoteValueHolder(ObjID id) {
        this.id = id;
    }

    /**
     * If the reference object is mapped thru one to one mapping and the object derives its primary key value
     * from this relationship then remote value holder has a primary key row for.
     */
    protected boolean canDoCacheCheck() {
        if ((getMapping() == null) || (getQuery() == null)) {
            return false;
        }

        return (getTargetObjectPrimaryKeys() != null) && getMapping().isOneToOneMapping() && (!getQuery().shouldRefreshIdentityMapResult()) && (!getQuery().shouldRefreshRemoteIdentityMapResult()) && (getQuery().shouldMaintainCache());
    }

    /**
     * Only the id is checked for equality check.
     */
    @Override
    public boolean equals(Object object) {
        if (!(object instanceof RemoteValueHolder)) {
            return false;
        }

        return getID().equals(((RemoteValueHolder)object).getID());
    }

    /**
     * This method is used to remove the RemoteValueHolder from the dispatcher on Garbage
     * collection from the client
     */
    @Override
    public void finalize() {
        if ((this.session != null) && (this.session instanceof RemoteSession) && ((RemoteSession)this.session).shouldEnableDistributedIndirectionGarbageCollection()) {
            // This must be on the client
            RemoveServerSideRemoteValueHolderCommand command = new RemoveServerSideRemoteValueHolderCommand(getID());
            ((DistributedSession)getSession()).getRemoteConnection().processCommand(command);
            //remove this value holder from the session dispatcher as it will no longer be needed
        }
    }

    /**
     * Return the unique id.
     */
    public ObjID getID() {
        return id;
    }

    /**
     * Return the associated mapping.
     */
    public DatabaseMapping getMapping() {
        return mapping;
    }

    /**
     * Get object from the cache if there is one.
     */
    protected Object getObjectFromCache() {
        Object cachedObject = null;

        if (getMapping().isOneToOneMapping()) {
            ClassDescriptor descriptor = getMapping().getReferenceDescriptor();
            cachedObject = getSession().getIdentityMapAccessorInstance().getFromIdentityMap(getTargetObjectPrimaryKeys(), descriptor.getJavaClass(), descriptor);
        }

        return cachedObject;
    }

    /**
     * Return the associated query.
     */
    public ObjectLevelReadQuery getQuery() {
        return query;
    }

    /**
     * Return the object on the server that holds on
     * to the remote value holder.
     * Currently used only by TransparentIndirection so we
     * can get back to the original IndirectContainer.
     */
    public Object getServerIndirectionObject() {
        return serverIndirectionObject;
    }

    /**
     * Get target object primary key row.
     */
    protected Object getTargetObjectPrimaryKeys() {
        return targetObjectPrimaryKeys;
    }

    /**
     * Return the original value holder.
     * This is null on the client side because it is tagged transient.
     * This is how we know whether the remote value holder is
     * being invoked on the client or on the server.
     */
    public ValueHolderInterface<Object> getWrappedServerValueHolder() {
        return wrappedServerValueHolder;
    }

    /**
     * Return the hashcode for id, because it is unqiue.
     */
    @Override
    public int hashCode() {
        return getID().hashCode();
    }

    /**
     * Return the object.
     */
    @Override
    public synchronized Object instantiate() {
        Object valueOfServerValueHolder = null;

        if (getWrappedServerValueHolder() != null) {// server invocation
            valueOfServerValueHolder = getWrappedServerValueHolder().getValue();
        } else {// client invocation
            // check whether object exists on the client
            if (canDoCacheCheck()) {
                valueOfServerValueHolder = getObjectFromCache();
            }

            // does not exist on the client - so invoke the value holder on the server
            if (valueOfServerValueHolder == null) {
                valueOfServerValueHolder = ((DistributedSession)getSession()).instantiateRemoteValueHolderOnServer(this);
            }
        }
        return valueOfServerValueHolder;
    }

    /**
     * INTERNAL:
     * Answers if this valueholder is easy to instantiate.
     * @return true if getValue() won't trigger a database read.
     */
    @Override
    public boolean isEasilyInstantiated() {
        // Nothing is easily instantiated when on the client side.
        return this.isInstantiated || ((this.wrappedServerValueHolder != null)
                && (!(this.wrappedServerValueHolder instanceof DatabaseValueHolder) || ((DatabaseValueHolder)this.wrappedServerValueHolder).isEasilyInstantiated()));
    }

    /**
     * INTERNAL:
     * Answers if this valueholder is a pessimistic locking one.  Such valueholders
     * are special in that they can be triggered multiple times by different
     * UnitsOfWork.  Each time a lock query will be issued.  Hence even if
     * instantiated it may have to be instantiated again, and once instantatiated
     * all fields can not be reset.
     * Note: This method is not thread-safe.  It must be used in a synchronizaed manner
     */
    @Override
    public boolean isPessimisticLockingValueHolder() {
        // This abstract method needs to be implemented but is not meaningfull for
        // this subclass.
        if (getWrappedServerValueHolder() != null) {
            return ((getWrappedServerValueHolder() instanceof DatabaseValueHolder) && ((DatabaseValueHolder)getWrappedServerValueHolder()).isPessimisticLockingValueHolder());
        } else {
            // Pessimistic locking may not be supported on remote sessions, but if
            // it is make every attempt to do the right thing.
            return ((getQuery() != null) && getQuery().isLockQuery(getSession()));
        }
    }

    /**
     * Triggers UnitOfWork valueholders directly without triggering the wrapped
     * valueholder (this).
     * <p>
     * When in transaction and/or for pessimistic locking the UnitOfWorkValueHolder
     * needs to be triggered directly without triggering the wrapped valueholder.
     * However only the wrapped valueholder knows how to trigger the indirection,
     * i.e. it may be a batchValueHolder, and it stores all the info like the row
     * and the query.
     * Note: This method is not thread-safe.  It must be used in a synchronizaed manner
     */
    @Override
    public Object instantiateForUnitOfWorkValueHolder(UnitOfWorkValueHolder unitOfWorkValueHolder) {
        if ((getWrappedServerValueHolder() != null) && (getWrappedServerValueHolder() instanceof DatabaseValueHolder)) {
            DatabaseValueHolder wrapped = (DatabaseValueHolder)getWrappedServerValueHolder();
            return wrapped.instantiateForUnitOfWorkValueHolder(unitOfWorkValueHolder);
        }

        // The scenario of triggering a valueholder in transaction when
        // the RemoteUnitOfWork is on the client side may be impossible.
        return unitOfWorkValueHolder.buildCloneFor(getValue());
    }

    /**
     *  Override the default serialization for a remote valueholder so as not to serialize the value
     *  Note: Changed for bug 3145211.  We used to use the java.io.Serializable interface, but need to convert
     *  to Externalizable interface to avoid sending extra data through the superclass's serialization
     */
    @Override
    public void readExternal(ObjectInput in) throws IOException, java.lang.ClassNotFoundException {
        this.id = (ObjID)in.readObject();
        this.targetObjectPrimaryKeys = in.readObject();
        this.row = (AbstractRecord)in.readObject();
        this.isInstantiated = in.readBoolean();
    }

    /**
     * Set the unique id.
     */
    protected void setID(ObjID anID) {
        this.id = anID;
    }

    /**
     * Set mapping
     */
    public void setMapping(DatabaseMapping mapping) {
        this.mapping = mapping;
    }

    /**
     * Set the query.
     */
    public void setQuery(ObjectLevelReadQuery query) {
        this.query = query;
    }

    /**
     * Set the object on the server that holds on
     * to the remote value holder.
     * Currently used only by TransparentIndirection so we
     * can get back to the original IndirectContainer.
     */
    public void setServerIndirectionObject(Object serverIndirectionObject) {
        this.serverIndirectionObject = serverIndirectionObject;
    }

    /**
     * Set target object primary keys.
     */
    public void setTargetObjectPrimaryKeys(Object primaryKeys) {
        this.targetObjectPrimaryKeys = primaryKeys;
    }

    /**
     * Set the object.
     */
    @Override
    public void setValue(Object theValue) {
        super.setValue(theValue);
        if (getWrappedServerValueHolder() != null) {
            // This is a local setting of remote value holder
            // and will only happen with basic indirection
            getWrappedServerValueHolder().setValue(theValue);
        }
    }

    /**
     * Set the original value holder.
     */
    public void setWrappedServerValueHolder(ValueHolderInterface wrappedServerValueHolder) {
        this.wrappedServerValueHolder = wrappedServerValueHolder;
    }

    /**
     *  Override the default serialization for a remote valueholder so as not to serialize the value
     *  Note: Changed for bug 3145211.  We used to use the java.io.Serializable interface, but need to convert
     *  to Externalizable interface to avoid sending extra data through the superclass's serialization
     */
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(id);
        out.writeObject(targetObjectPrimaryKeys);
        out.writeObject(row);
        out.writeBoolean(false);
    }
}
