/*
 * Copyright (c) 1998, 2020 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.util.*;

import org.eclipse.persistence.indirection.*;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.internal.descriptors.*;
import org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder;

/**
 * Helper class for RemoteSessionController.
 * This descriptor iterator will replace all the normal
 * value holders in an object with remote value holders
 * that can be serialized to the client.
 */
public class ReplaceValueHoldersIterator extends DescriptorIterator {
    RemoteSessionController controller;

    /**
     * default constructor
     */
    private ReplaceValueHoldersIterator() {
        super();
    }

    /**
     * public constructor
     */
    public ReplaceValueHoldersIterator(RemoteSessionController controller) {
        this();
        this.initialize(controller);
    }

    /**
     * build and return an object descriptor for the specified object
     */
    protected ObjectDescriptor buildObjectDescriptor(Object object) {
        return controller.buildObjectDescriptor(object);
    }

    /**
     * build a properly initialized remote value holder
     */
    protected RemoteValueHolder buildRemoteValueHolderFor(ValueHolderInterface valueHolder) {
        RemoteValueHolder remoteValueHolder = null;

        if (valueHolder instanceof RemoteValueHolder) {
            remoteValueHolder = (RemoteValueHolder)valueHolder;
        } else if ((valueHolder instanceof UnitOfWorkValueHolder) && ((UnitOfWorkValueHolder)valueHolder).getWrappedValueHolder() instanceof RemoteValueHolder) {
            return (RemoteValueHolder)((UnitOfWorkValueHolder)valueHolder).getWrappedValueHolder();
        } else {
            remoteValueHolder = new RemoteValueHolder();
            remoteValueHolder.setWrappedServerValueHolder(valueHolder);
            remoteValueHolder.setMapping(this.getCurrentMapping());
        }
        saveRemoteValueHolder(remoteValueHolder);
        return remoteValueHolder;
    }

    /**
     * initialize instance
     */
    protected void initialize(RemoteSessionController controller) {
        this.controller = controller;
    }

    /**
     * Iterate an indirect container.
     */
    @Override
    protected void internalIterateIndirectContainer(IndirectContainer container) {
        ValueHolderInterface containedValueHolder = container.getValueHolder();

        if (containedValueHolder instanceof RemoteValueHolder) {
            containedValueHolder = ((RemoteValueHolder)containedValueHolder).getWrappedServerValueHolder();
        }

        synchronized (containedValueHolder) {
            // extract VH within sync block to ensure correct one is used.
            ValueHolderInterface valueHolder = container.getValueHolder();
            RemoteValueHolder remoteValueHolder = buildRemoteValueHolderFor(valueHolder);

            container.setValueHolder(remoteValueHolder);
            remoteValueHolder.setServerIndirectionObject(container);
        }
    }

    /**
     * Synchronously create a remote value holder. The value holder passed in is ignored
     * so that we can ensure that the value holder being held by the object is used
     * instead of the one that was passed in.
     */
    @Override
    protected void internalIterateValueHolder(ValueHolderInterface originalValueHolder) {
        ValueHolderInterface rootValueHolder = originalValueHolder;

        // Ensure we have the base server side value holder. There will only be one of these per server.
        if (rootValueHolder instanceof RemoteValueHolder) {
            rootValueHolder = ((RemoteValueHolder)rootValueHolder).getWrappedServerValueHolder();
        }
        synchronized (rootValueHolder) {
            ValueHolderInterface valueHolder = (ValueHolderInterface)getCurrentMapping().getAttributeValueFromObject(getVisitedParent());
            RemoteValueHolder remoteValueHolder = buildRemoteValueHolderFor(valueHolder);

            if (valueHolder != remoteValueHolder) {
                if (this.getCurrentMapping().isOneToOneMapping()) {
                    this.setOneToOneMappingSettingsIn(remoteValueHolder);
                }
                this.getCurrentMapping().setAttributeValueInObject(this.getVisitedParent(), remoteValueHolder);
            }
        }
    }

    /**
     * if we get here, it is a domain object
     */
    @Override
    protected void iterate(Object object) {
        ((Map)getResult()).put(object, this.buildObjectDescriptor(object));
    }

    /**
     * save the remote value holder for later use
     */
    protected void saveRemoteValueHolder(RemoteValueHolder remoteValueHolder) {
        controller.saveRemoteValueHolder(remoteValueHolder);
    }

    /**
     * Set one-to-one mapping information.
     * This allows us to look for a cache hit
     * before going to the database.
     */
    protected void setOneToOneMappingSettingsIn(RemoteValueHolder remoteValueHolder) {
        ObjectReferenceMapping oneToOneMapping = (ObjectReferenceMapping)this.getCurrentMapping();// cast it
        if (oneToOneMapping.getDescriptor().getObjectBuilder().isPrimaryKeyMapping(oneToOneMapping)) {
            remoteValueHolder.setRow(oneToOneMapping.extractPrimaryKeyRowForSourceObject(this.getVisitedParent(), this.getSession()));
        }
        remoteValueHolder.setTargetObjectPrimaryKeys(oneToOneMapping.extractPrimaryKeysForReferenceObject(this.getVisitedParent(), this.getSession()));
    }
}
