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

import java.io.Serializable;
import java.util.Map;

import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.IntegrityChecker;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.sessions.remote.ObjectDescriptor;
import org.eclipse.persistence.internal.sessions.remote.RemoteValueHolder;
import org.eclipse.persistence.mappings.CollectionMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.mappings.ObjectReferenceMapping;
import org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.sessions.remote.DistributedSession;

/**
 * <h2>Purpose</h2>:
 * <p>
 * An IndirectionPolicy acts as a 'rules' holder that determines
 * the behavior of a ForeignReferenceMapping (or TransformationMapping)
 * with respect to indirection, or lack thereof.
 * </p>
 * <h3>Description</h3>:
 * <p>
 * IndirectionPolicy is an abstract class that defines the protocol to be implemented by
 * subclasses so that the assorted DatabaseMappings can use an assortment of
 * indirection policies:</p><ul>
 * <li> no indirection policy (read everything from database)
 * <li> basic indirection policy (use ValueHolders)
 * <li> transparent indirection policy (collections only)
 * <li> proxy indirection policy (transparent 1:1 indirection using JDK 1.3's <CODE>Proxy</CODE>)
 * </ul>
 *
 * <h3>Responsibilities</h3>:
 *     <ul>
 *     <li>instantiate the various IndirectionPolicies
 *     </ul>
 *
 * @see ForeignReferenceMapping
 * @author Mike Norman
 * @since TOPLink/Java 2.5
 */
public abstract class IndirectionPolicy implements Cloneable, Serializable {
    protected DatabaseMapping mapping;

    /**
     * INTERNAL:
     * Construct a new indirection policy.
     */
    protected IndirectionPolicy() {
        super();
    }

    /**
     * INTERNAL:
     *    Return a backup clone of the attribute.
     */
    public Object backupCloneAttribute(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        return this.mapping.buildBackupCloneForPartObject(attributeValue, clone, backup, unitOfWork);
    }

    /**
     * INTERNAL
     * Return true if the refresh should refresh on this mapping or not.
     */
    protected ReadObjectQuery buildCascadeQuery(MergeManager mergeManager) {
        ReadObjectQuery query = new ReadObjectQuery();
        if (this.mapping.getReferenceDescriptor() != null) {
            query.setReferenceClass(this.mapping.getReferenceDescriptor().getJavaClass());
        }
        if (mergeManager.shouldCascadeAllParts()) {
            query.cascadeAllParts();
            query.refreshIdentityMapResult();
        }
        if (mergeManager.shouldCascadePrivateParts() && getForeignReferenceMapping().isPrivateOwned()) {
            query.cascadePrivateParts();
            query.refreshIdentityMapResult();
        }

        return query;
    }

    /**
     * INTERNAL: This method can be used when an Indirection Object is required
     * to be built from a provided ValueHolderInterface object. This may be used
     * for custom value holder types. Certain policies like the
     * TransparentIndirectionPolicy may wrap the valueholder in another object.
     */

    public abstract Object buildIndirectObject(ValueHolderInterface valueHolder);

    /**
     * INTERNAL:
     * Clones itself.
     */
    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }

    /**
     * INTERNAL:
     * Return a clone of the attribute.
     *  @param buildDirectlyFromRow indicates that we are building the clone
     *  directly from a row as opposed to building the original from the
     *  row, putting it in the shared cache, and then cloning the original.
     */
    public abstract Object cloneAttribute(Object attributeValue, Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession, boolean buildDirectlyFromRow);

    /**
     * INTERNAL:
     * Return the primary key for the reference object (i.e. the object
     * object referenced by domainObject and specified by mapping).
     * This key will be used by a RemoteValueHolder.
     */
    public Object extractPrimaryKeyForReferenceObject(Object referenceObject, AbstractSession session) {
        return getOneToOneMapping().extractPrimaryKeysFromRealReferenceObject(referenceObject, session);
    }

    /**
     * INTERNAL:
     * Return the reference row for the reference object.
     * This allows the new row to be built without instantiating
     * the reference object.
     * Return null if the object has already been instantiated.
     */
    public abstract AbstractRecord extractReferenceRow(Object referenceObject);

    /**
     * INTERNAL:
     * An object has been serialized from the server to the client.
     * Replace the transient attributes of the remote value holders
     * with client-side objects.
     */
    public abstract void fixObjectReferences(Object object, Map<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> processedObjects, ObjectLevelReadQuery query, DistributedSession session);

    /**
     * INTERNAL:
     * Reduce casting clutter....
     */
    protected CollectionMapping getCollectionMapping() {
        return (CollectionMapping)this.mapping;
    }

    /**
     * INTERNAL:
     * Reduce casting clutter....
     */
    protected ForeignReferenceMapping getForeignReferenceMapping() {
        return (ForeignReferenceMapping)this.mapping;
    }

    /**
     * INTERNAL:
     * Return the database mapping that uses the indirection policy.
     */
    public DatabaseMapping getMapping() {
        return mapping;
    }

    /**
     * INTERNAL:
     * Reduce casting clutter....
     */
    protected ObjectReferenceMapping getOneToOneMapping() {
        return (ObjectReferenceMapping)this.mapping;
    }

    /**
     * INTERNAL:
     * Return the original indirection object for a unit of work indirection object.
     */
    public abstract Object getOriginalIndirectionObject(Object unitOfWorkIndirectionObject, AbstractSession session);

    /**
     * INTERNAL:
     *    Return the original indirection object for a unit of work indirection object.
     */
    public Object getOriginalIndirectionObjectForMerge(Object unitOfWorkIndirectionObject, AbstractSession session){
        return getOriginalIndirectionObject(unitOfWorkIndirectionObject, session);
    }

    /**
     * INTERNAL: Return the original valueHolder object. Access to the
     * underlying valueholder may be required when serializing the valueholder
     * or converting the valueHolder to another type.
     */
    public abstract Object getOriginalValueHolder(Object unitOfWorkIndirectionObject, AbstractSession session);

    /**
     * INTERNAL:
     * Return the "real" attribute value, as opposed to any wrapper.
     * This will trigger the wrapper to instantiate the value.
     */
    public abstract Object getRealAttributeValueFromObject(Object object, Object attribute);

    /**
     * INTERNAL:
     * Trigger the instantiation of the value.
     */
    public void instantiateObject(Object object, Object attribute) {
        getRealAttributeValueFromObject(object, attribute);
    }

    /**
     * INTERNAL:
     * Reduce casting clutter....
     */
    protected AbstractTransformationMapping getTransformationMapping() {
        return (AbstractTransformationMapping)this.mapping;
    }

    /**
     * INTERNAL:
     * Extract and return the appropriate value from the
     * specified remote value holder.
     */
    public abstract Object getValueFromRemoteValueHolder(RemoteValueHolder<?> remoteValueHolder);

    /**
     * INTERNAL:
     * The method validateAttributeOfInstantiatedObject(Object attributeValue) fixes the value of the attributeValue
     * in cases where it is null and indirection requires that it contain some specific data structure.  Return whether this will happen.
     * This method is used to help determine if indirection has been triggered
     * @see #validateAttributeOfInstantiatedObject(Object)
     */
    public boolean isAttributeValueFullyBuilt(Object attributeValue){
        return true;
    }

    /**
     * INTERNAL:
     * Initialize the indirection policy (Do nothing by default)
     */
    public void initialize() {
    }

    /**
     * INTERNAL:
     */
    public boolean isWeavedObjectBasicIndirectionPolicy() {
        return false;
    }

    /**
     * INTERNAL:
     * Iterate over the specified attribute value,
     * heeding the settings in the iterator.
     */
    public void iterateOnAttributeValue(DescriptorIterator iterator, Object attributeValue) {
        if (attributeValue != null) {
            this.mapping.iterateOnRealAttributeValue(iterator, attributeValue);
        }
    }

    /**
     * INTERNAL
     * Replace the client value holder with the server value holder,
     * after copying some of the settings from the client value holder.
     */
    protected void mergeClientIntoServerValueHolder(RemoteValueHolder<?> serverValueHolder, MergeManager mergeManager) {
        serverValueHolder.setMapping(this.mapping);
        serverValueHolder.setSession(mergeManager.getSession());

        if (this.mapping.isForeignReferenceMapping()) {
            ObjectLevelReadQuery query = buildCascadeQuery(mergeManager);
            serverValueHolder.setQuery(query);
        }
    }

    /**
     * INTERNAL
     * Replace the client value holder with the server value holder,
     * after copying some of the settings from the client value holder.
     */
    public abstract void mergeRemoteValueHolder(Object clientSideDomainObject, Object serverSideDomainObject, MergeManager mergeManager);

    /**
     * INTERNAL:
     * Return the null value of the appropriate attribute. That is, the
     * field from the database is NULL, return what should be
     * placed in the object's attribute as a result.
     */
    public abstract Object nullValueFromRow();

    /**
     * INTERNAL:
     * Return whether the specified object is instantiated.
     */
    public abstract boolean objectIsInstantiated(Object object);

    /**
     * INTERNAL:
     * Return whether the specified object can be instantiated without database access.
     */
    public abstract boolean objectIsEasilyInstantiated(Object object);

    /**
     * INTERNAL:
     * Return whether the specified object is instantiated, or if it has changes.
     */
    public boolean objectIsInstantiatedOrChanged(Object object) {
        return objectIsInstantiated(object);
    }

    /**
     * INTERNAL:
     * set the database mapping that uses the indirection policy.
     */
    public void setMapping(DatabaseMapping mapping) {
        this.mapping = mapping;
    }

    /**
     * INTERNAL:
     * Set the value of the appropriate attribute of target to attributeValue.
     * In this case, simply place the value inside the target.
     */
    public void setRealAttributeValueInObject(Object target, Object attributeValue) {
        this.mapping.setAttributeValueInObject(target, attributeValue);
    }

    /**
     * INTERNAL:
     * Same functionality as setRealAttributeValueInObject(Object target, Object attributeValue) but allows
     * overridden behavior for IndirectionPolicies that track changes
     */
    public void setRealAttributeValueInObject(Object target, Object attributeValue, boolean allowChangeTracking) {
        setRealAttributeValueInObject(target, attributeValue);
    }

    /**
     * INTERNAL:
     * set the source object into QueryBasedValueHolder.
     * Used only by transparent indirection.
     */
    public void setSourceObject(Object sourceObject, Object attributeValue) {
    }

    /**
     * ADVANCED:
     * This method will only change the behavior of TransparentIndirectionPolicy.
     *
     * IndirectList and IndirectSet can be configured not to instantiate the list from the
     * database when you add and remove from them.  IndirectList defaults to this behavior. When
     * Set to true, the collection associated with this TransparentIndirection will be setup so as
     * not to instantiate for adds and removes.  The weakness of this setting for an IndirectSet is
     * that when the set is not instantiated, if a duplicate element is added, it will not be
     * detected until commit time.
     *
     */
    public void setUseLazyInstantiation(Boolean useLazyInstantiation) {
    }

    /**
     * ADVANCED:
     * Returns false unless this is a transparent indirection policy
     *
     * IndirectList and IndirectSet can be configured not to instantiate the list from the
     * database when you add and remove from them.  IndirectList defaults to this behavior. When
     * Set to true, the collection associated with this TransparentIndirection will be setup so as
     * not to instantiate for adds and removes.  The weakness of this setting for an IndirectSet is
     * that when the set is not instantiated, if a duplicate element is added, it will not be
     * detected until commit time.
     */
    public Boolean shouldUseLazyInstantiation() {
        return false;
    }
    /**
     * Reset the wrapper used to store the value.
     * This is only required if a wrapper is used.
     */
    public void reset(Object target) {
        // Nothing by default.
    }

    /**
     * INTERNAL:
     * Return whether the indirection policy actually uses indirection.
     * The default is true.
     */
    public boolean usesIndirection() {
        return true;
    }

    /**
     * INTERNAL:
     * Return whether the indirection policy uses transparent indirection.
     * The default is false.
     */
    public boolean usesTransparentIndirection(){
        return false;
    }

    /**
     * INTERNAL:
     * Verify that the value of the attribute within an instantiated object
     * is of the appropriate type for the indirection policy.
     * If it is incorrect, throw an exception.
     * If the value is null return a new indirection object to be used for the attribute.
     */
    public Object validateAttributeOfInstantiatedObject(Object attributeValue) throws DescriptorException {
        return attributeValue;
    }

    /**
     * INTERNAL:
     * Verify that the container policy is compatible with the
     * indirection policy. If it is incorrect, add an exception to the
     * integrity checker.
     */
    public void validateContainerPolicy(IntegrityChecker checker) throws DescriptorException {
        // by default, do nothing
    }

    /**
     * INTERNAL:
     * Verify that attributeType is correct for the
     * indirection policy. If it is incorrect, add an exception to the
     * integrity checker.
     */
    public void validateDeclaredAttributeType(Class<?> attributeType, IntegrityChecker checker) throws DescriptorException {
        // by default, do nothing
    }

    /**
     * INTERNAL:
     * Verify that attributeType is an appropriate collection type for the
     * indirection policy. If it is incorrect, add an exception to the integrity checker.
     */
    public void validateDeclaredAttributeTypeForCollection(Class<?> attributeType, IntegrityChecker checker) throws DescriptorException {
        // by default, do nothing
    }

    /**
     * INTERNAL:
     * Verify that getter returnType is correct for the
     * indirection policy. If it is incorrect, add an exception
     * to the integrity checker.
     */
    public void validateGetMethodReturnType(Class<?> returnType, IntegrityChecker checker) throws DescriptorException {
        // by default, do nothing
    }

    /**
     * INTERNAL:
     * Verify that getter returnType is an appropriate collection type for the
     * indirection policy. If it is incorrect, add an exception to the integrity checker.
     */
    public void validateGetMethodReturnTypeForCollection(Class<?> returnType, IntegrityChecker checker) throws DescriptorException {
        // by default, do nothing
    }

    /**
     * INTERNAL:
     * Verify that setter parameterType is correct for the
     * indirection policy. If it is incorrect, add an exception
     * to the integrity checker.
     */
    public void validateSetMethodParameterType(Class<?> parameterType, IntegrityChecker checker) throws DescriptorException {
        // by default, do nothing
    }

    /**
     * INTERNAL:
     * Verify that setter parameterType is an appropriate collection type for the
     * indirection policy. If it is incorrect, add an exception to the integrity checker.
     */
    public void validateSetMethodParameterTypeForCollection(Class<?> parameterType, IntegrityChecker checker) throws DescriptorException {
        // by default, do nothing
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by the batchQuery.
     */
    public abstract Object valueFromBatchQuery(ReadQuery batchQuery, AbstractRecord row, ObjectLevelReadQuery originalQuery, CacheKey parentCacheKey);

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by invoking the appropriate
     * method on the object and passing it the row and session.
     */
    public abstract Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session);

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by the query.
     */
    public abstract Object valueFromQuery(ReadQuery query, AbstractRecord row, Object sourceObject, AbstractSession session);

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by the query.
     */
    public abstract Object valueFromQuery(ReadQuery query, AbstractRecord row, AbstractSession session);

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by the row.
     */
    public abstract Object valueFromRow(Object object);
}
