/*
 * 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.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Map;

import org.eclipse.persistence.descriptors.changetracking.ChangeTracker;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.IntegrityChecker;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.queries.InterfaceContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
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.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.sessions.remote.DistributedSession;

/**
 * <h2>Purpose</h2>:
 * NoIndirectionPolicy implements the behavior necessary for a
 * a <code>org.eclipse.persistence.mappings.ForeignReferenceMapping</code> (or TransformationMapping) to
 * directly use domain objects, as opposed to ValueHolders.
 *
 * @author Mike Norman
 * @since TOPLink/Java 2.5
 */
public class NoIndirectionPolicy extends IndirectionPolicy {

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

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

    @Override
    public Object buildIndirectObject(ValueHolderInterface valueHolder){
        return valueHolder.getValue();
    }

    /**
     * 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.
     */
    @Override
    public Object cloneAttribute(Object attributeValue, Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession, boolean buildDirectlyFromRow) {
        // Since valueFromRow was called with the UnitOfWork, attributeValue
        // is already a registered result.
        if (buildDirectlyFromRow) {
            return attributeValue;
        }
        if (!cloningSession.isUnitOfWork()){
            return mapping.buildContainerClone(attributeValue, cloningSession);
        }
        boolean isExisting = !cloningSession.isUnitOfWork() || (((UnitOfWorkImpl) cloningSession).isObjectRegistered(clone) && (!(((UnitOfWorkImpl)cloningSession).isOriginalNewObject(original))));
        return this.getMapping().buildCloneForPartObject(attributeValue, original, cacheKey, clone, cloningSession, refreshCascade, isExisting, isExisting);// only assume from shared cache if it is existing
    }

    /**
     * INTERNAL:
     * Return whether the collection type is appropriate for the indirection policy.
     * In this case, the type MUST be a Vector (or, in the case of jdk1.2,
     * Collection or Map).
     */
    protected boolean collectionTypeIsValid(Class<?> collectionType) {
        return getCollectionMapping().getContainerPolicy().isValidContainerType(collectionType);
    }

    /**
     * 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.
     */
    @Override
    public AbstractRecord extractReferenceRow(Object referenceObject) {
        return null;
    }

    /**
     * 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.
     */
    @Override
    public void fixObjectReferences(Object object, Map<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> processedObjects, ObjectLevelReadQuery query, DistributedSession session) {
        this.mapping.fixRealObjectReferences(object, objectDescriptors, processedObjects, query, session);
    }

    /**
     * INTERNAL:
     * Return the original indirection object for a unit of work indirection object.
     */
    @Override
    public Object getOriginalIndirectionObject(Object unitOfWorkIndirectionObject, AbstractSession session) {
        // This code appears broken, but actually is unreachable because
        // only called when indirection is true.
        return unitOfWorkIndirectionObject;
    }

    /**
     * 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.
     */
    @Override
    public Object getOriginalValueHolder(Object unitOfWorkIndirectionObject, AbstractSession session){
        return unitOfWorkIndirectionObject;
    }

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

    /**
     * INTERNAL:
     * Extract and return the appropriate value from the
     * specified remote value holder.
     */
    @Override
    public Object getValueFromRemoteValueHolder(RemoteValueHolder<?> remoteValueHolder) {
        throw DescriptorException.invalidIndirectionPolicyOperation(this, "getValueFromRemoteValueHolder");
    }

    /**
     * INTERNAL
     * Replace the client value holder with the server value holder,
     * after copying some of the settings from the client value holder.
     */
    @Override
    public void mergeRemoteValueHolder(Object clientSideDomainObject, Object serverSideDomainObject, org.eclipse.persistence.internal.sessions.MergeManager mergeManager) {
        throw DescriptorException.invalidIndirectionPolicyOperation(this, "mergeRemoteValueHolder");
    }

    /**
     * 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.
     */
    @Override
    public Object nullValueFromRow() {
        return null;
    }

    /**
     * INTERNAL:
     * Return whether the specified object is instantiated.
     */
    @Override
    public boolean objectIsInstantiated(Object object) {
        return true;
    }

    /**
     * INTERNAL:
     * Return whether the specified object can be instantiated without database access.
     */
    @Override
    public boolean objectIsEasilyInstantiated(Object object) {
        return true;
    }

    /**
     * INTERNAL:
     * Return whether the type is appropriate for the indirection policy.
     * In this case, the attribute type CANNOT be ValueHolderInterface.
     */
    protected boolean typeIsValid(Class<?> attributeType) {
        return attributeType != ClassConstants.ValueHolderInterface_Class;
    }

    /**
     * INTERNAL:
     * Return whether the indirection policy actually uses indirection.
     * Here, we must reply false.
     */
    @Override
    public boolean usesIndirection() {
        return false;
    }

    /**
     * INTERNAL:
     * Verify that attributeType is correct for the
     * indirection policy. If it is incorrect, add an exception to the
     * integrity checker.
     * In this case, the attribute type CANNOT be ValueHolderInterface.
     */
    @Override
    public void validateDeclaredAttributeType(Class<?> attributeType, IntegrityChecker checker) throws DescriptorException {
        super.validateDeclaredAttributeType(attributeType, checker);
        if (!this.typeIsValid(attributeType)) {
            checker.handleError(DescriptorException.attributeAndMappingWithoutIndirectionMismatch(this.mapping));
        }
    }

    /**
     * INTERNAL:
     * Verify that attributeType is an appropriate collection type for the
     * indirection policy. If it is incorrect, add an exception to the integrity checker.
     * In this case, the type MUST be a Vector (or, in the case of jdk1.2,
     * Collection or Map).
     */
    @Override
    public void validateDeclaredAttributeTypeForCollection(Class<?> attributeType, IntegrityChecker checker) throws DescriptorException {
        super.validateDeclaredAttributeTypeForCollection(attributeType, checker);
        if (!this.collectionTypeIsValid(attributeType)) {
            InterfaceContainerPolicy policy = (InterfaceContainerPolicy)getCollectionMapping().getContainerPolicy();
            checker.handleError(DescriptorException.attributeTypeNotValid(this.getCollectionMapping(), policy.getInterfaceType()));
        }
    }

    /**
     * INTERNAL:
     *    Verify that getter returnType is correct for the
     * indirection policy. If it is incorrect, add an exception
     * to the integrity checker.
     * In this case, the return type CANNOT be ValueHolderInterface.
     */
    @Override
    public void validateGetMethodReturnType(Class<?> returnType, IntegrityChecker checker) throws DescriptorException {
        super.validateGetMethodReturnType(returnType, checker);
        if (!this.typeIsValid(returnType)) {
            checker.handleError(DescriptorException.returnAndMappingWithoutIndirectionMismatch(this.mapping));
        }
    }

    /**
     * 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.
     * In this case, the type MUST be a Vector (or, in the case of jdk1.2,
     * Collection or Map).
     */
    @Override
    public void validateGetMethodReturnTypeForCollection(Class<?> returnType, IntegrityChecker checker) throws DescriptorException {
        super.validateGetMethodReturnTypeForCollection(returnType, checker);
        if (!this.collectionTypeIsValid(returnType)) {
            checker.handleError(DescriptorException.getMethodReturnTypeNotValid(getCollectionMapping()));
        }
    }

    /**
     * INTERNAL:
     * Verify that setter parameterType is correct for the
     * indirection policy. If it is incorrect, add an exception
     * to the integrity checker.
     * In this case, the parameter type CANNOT be ValueHolderInterface.
     */
    @Override
    public void validateSetMethodParameterType(Class<?> parameterType, IntegrityChecker checker) throws DescriptorException {
        super.validateSetMethodParameterType(parameterType, checker);
        if (!this.typeIsValid(parameterType)) {
            checker.handleError(DescriptorException.parameterAndMappingWithoutIndirectionMismatch(this.mapping));
        }
    }

    /**
     * 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.
     * In this case, the type MUST be a Vector (or, in the case of jdk1.2,
     * Collection or Map).
     */
    @Override
    public void validateSetMethodParameterTypeForCollection(Class<?> parameterType, IntegrityChecker checker) throws DescriptorException {
        super.validateSetMethodParameterTypeForCollection(parameterType, checker);
        if (!this.collectionTypeIsValid(parameterType)) {
            checker.handleError(DescriptorException.setMethodParameterTypeNotValid(getCollectionMapping()));
        }
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by the batchQuery.
     * In this case, extract the result from the query.
     */
    @Override
    public Object valueFromBatchQuery(ReadQuery batchQuery, AbstractRecord row, ObjectLevelReadQuery originalQuery, CacheKey parentCacheKey) {
        return getForeignReferenceMapping().extractResultFromBatchQuery(batchQuery, parentCacheKey, row, originalQuery.getSession(), originalQuery);
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by invoking the mapping's AttributeTransformer
     */
    @Override
    public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) {
        return getTransformationMapping().invokeAttributeTransformer(row, object, session);
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     *    This value is determined by the query.
     * In this case, wrap the query in a ValueHolder for later invocation.
     */
    @Override
    public Object valueFromQuery(ReadQuery query, AbstractRecord row, Object sourceObject, AbstractSession session) {
        return valueFromQuery(query, row, session);
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by the query.
     * In this case, simply execute the query and return its results.
     */
    @Override
    public Object valueFromQuery(ReadQuery query, AbstractRecord row, AbstractSession session) {
        return session.executeQuery(query, row);
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by the row.
     * In this case, simply return the object.
     */
    @Override
    public Object valueFromRow(Object object) {
        return object;
    }

    /**
     * Set the value of the appropriate attribute of target to attributeValue.
     * In this case, place the value inside the target's ValueHolder.
     * if trackChanges is true, set the value in the object as if the user was setting it.  Allow change tracking to pick up the change.
     */
    @Override
    public void setRealAttributeValueInObject(Object target, Object attributeValue, boolean trackChanges) {
        Object oldValue = null;
        if (trackChanges && (target instanceof ChangeTracker)) {
            oldValue = getRealAttributeValueFromObject(target, mapping.getAttributeValueFromObject(target));
        }
        setRealAttributeValueInObject(target, attributeValue);
        if (trackChanges && (target instanceof ChangeTracker)) {
            PropertyChangeListener listener = ((ChangeTracker) target)._persistence_getPropertyChangeListener();
            if (listener != null && attributeValue != oldValue)
            {
                listener.propertyChange(new PropertyChangeEvent(target, mapping.getAttributeName(), oldValue, attributeValue));
            }
        }
    }
}
