/*
 * 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.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.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 objectDescriptors, Map 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));
            }
        }
    }
}
