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

import java.io.Serializable;

import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.indirection.WeavedAttributeValueHolderInterface;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.localization.ToStringLocalization;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;

/**
 * DatabaseValueHolder wraps a database-stored object and implements
 * behavior to access it. The object is read only once from database
 * after which is cached for faster access.
 *
 * @see ValueHolderInterface
 * @author    Dorin Sandu
 */
public abstract class DatabaseValueHolder implements WeavedAttributeValueHolderInterface, Cloneable, Serializable {

    /** Stores the object after it is read from the database. */
    protected volatile Object value;

    /** Indicates whether the object has been read from the database or not. */
    protected volatile boolean isInstantiated;

    /** Stores the session for the database that contains the object. */
    protected transient AbstractSession session;

    /** Stores the row representation of the object. */
    // Cannot be transient as may be required to extract the pk from a serialized object.
    protected AbstractRecord row;

    /**
     * The variable below is used as part of the implementation of WeavedAttributeValueHolderInterface
     * It is used to track whether a valueholder that has been weaved into a class is coordinated
     * with the underlying property
     * Set internally in EclipseLink when the state of coordination between a weaved valueholder and the underlying property is known
     */
    protected boolean isCoordinatedWithProperty = false;

    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException exception) {
            throw new InternalError();
        }
    }

    /**
     * Return the row.
     */
    public AbstractRecord getRow() {
        return row;
    }

    /**
     * Return the session.
     */
    public AbstractSession getSession() {
        return session;
    }

    public ValueHolderInterface getWrappedValueHolder() {
        return null;
    }

    /**
     * Return the object.
     */
    @Override
    public Object getValue() {
        boolean instantiated = this.isInstantiated;
        if (!instantiated) {
            synchronized (this) {
                instantiated = this.isInstantiated;
                if (!instantiated) {
                    // The value must be set directly because the setValue can also cause instantiation under UOW.
                    privilegedSetValue(instantiate());
                    this.isInstantiated = true;
                    postInstantiate();
                    resetFields();
                }
            }
        }
        return value;
    }

    /**
     * Process against the UOW and attempt to load a local copy before going to the shared cache
     * If null is returned then the calling UOW will instantiate as normal.
     */
    public Object getValue(UnitOfWorkImpl uow) {
        //This method simply returns null as this will cause the UOWVH to trigger
        //the relationship normally.
        return null;
    }

    /**
     * Instantiate the object.
     */
    protected abstract Object instantiate() throws DatabaseException;

    /**
     * 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: Implementations of this method are not necessarily thread-safe.  They must
     * be used in a synchronized manner
     */
    public abstract Object instantiateForUnitOfWorkValueHolder(UnitOfWorkValueHolder unitOfWorkValueHolder);

    /**
     * This method is used as part of the implementation of WeavedAttributeValueHolderInterface
     * It is used to check whether a valueholder that has been weaved into a class is coordinated
     * with the underlying property
     */
    @Override
    public boolean isCoordinatedWithProperty(){
        return isCoordinatedWithProperty;
    }

    /**
     * This method is used as part of the implementation of WeavedAttributeValueHolderInterface.
     *
     * A DatabaseValueHolder is set up by TopLink and will never be a newly weaved valueholder.
     * As a result, this method is stubbed out.
     */
    @Override
    public boolean isNewlyWeavedValueHolder(){
        return false;
    }

    /**
     * INTERNAL:
     * Answers if this valueholder is easy to instantiate.
     * @return true if getValue() won't trigger a database read.
     */
    public boolean isEasilyInstantiated() {
        return this.isInstantiated;
    }

    /**
     * Return a boolean indicating whether the object
     * has been read from the database or not.
     */
    @Override
    public boolean isInstantiated() {
        return isInstantiated;
    }

    /**
     * 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 instantiated
     * all fields can not be reset.
     * Note: Implementations of this method are not necessarily thread-safe.  They must
     * be used in a synchronizaed manner
     */
    public abstract boolean isPessimisticLockingValueHolder();

    /**
     * Answers if this valueholder is referenced only by a UnitOfWork valueholder.
     * I.e. it was built in valueFromRow which was called by buildCloneFromRow.
     * <p>
     * Sometimes in transaction a UnitOfWork clone, and all valueholders, are built
     * directly from the row; however a UnitOfWorkValueHolder does not know how to
     * instantiate itself so wraps this which does.
     * <p>
     * On a successful merge must be released to the session cache with
     * releaseWrappedValueHolder.
     */
    protected boolean isTransactionalValueHolder() {
        return ((session != null) && session.isUnitOfWork());
    }

    /**
     * Used to determine if this is a remote uow value holder that was serialized to the server.
     * It has no reference to its wrapper value holder, so must find its original object to be able to instantiate.
     */
    public boolean isSerializedRemoteUnitOfWorkValueHolder() {
        return false;
    }

    /**
     * INTERNAL:
     * Run any extra code required after the valueholder instantiates
     * @see QueryBasedValueHolder
     */
    public void postInstantiate(){
        //noop
    }

    /**
     * Set the object. This is used only by the privileged methods. One must be very careful in using this method.
     */
    public void privilegedSetValue(Object value) {
        this.value = value;
        isCoordinatedWithProperty = false;
    }

    /**
     * Releases a wrapped valueholder privately owned by a particular unit of work.
     * <p>
     * When unit of work clones are built directly from rows no object in the shared
     * cache points to this valueholder, so it can store the unit of work as its
     * session.  However once that UnitOfWork commits and the valueholder is merged
     * into the shared cache, the session needs to be reset to the root session, ie.
     * the server session.
     */
    public void releaseWrappedValueHolder(AbstractSession targetSession) {
        AbstractSession session = this.session;
        if ((session != null) && session.isUnitOfWork()) {
            this.session = targetSession;
        }
    }

    /**
     * Reset all the fields that are not needed after instantiation.
     */
    protected void resetFields() {
        this.row = null;
        this.session = null;
    }

    /**
     * This method is used as part of the implementation of WeavedAttributeValueHolderInterface
     * It is used internally by EclipseLink to set whether a valueholder that has been weaved into a class is coordinated
     * with the underlying property
     */
    @Override
    public void setIsCoordinatedWithProperty(boolean coordinated){
        this.isCoordinatedWithProperty = coordinated;
    }

    /**
     * This method is used as part of the implementation of WeavedAttributeValueHolderInterface
     *
     * A DatabaseValueHolder is set up by EclipseLink and will never be a newly weaved valueholder
     * As a result, this method is stubbed out.
     */
    @Override
    public void setIsNewlyWeavedValueHolder(boolean isNew){
    }

    /**
     * Set the instantiated flag to true.
     */
    public void setInstantiated() {
        isInstantiated = true;
    }

    /**
     * Set the row.
     */
    public void setRow(AbstractRecord row) {
        this.row = row;
    }

    /**
     * Set the session.
     */
    public void setSession(AbstractSession session) {
        this.session = session;
    }

    /**
     * Set the instantiated flag to false.
     */
    public void setUninstantiated() {
        isInstantiated = false;
    }

    /**
     * Set the object.
     */
    @Override
    public void setValue(Object value) {
        this.value = value;
        setInstantiated();
    }

    /**
     * INTERNAL:
     * Return if add/remove should trigger instantiation or avoid.
     * Current instantiation is avoided is using change tracking.
     */
    @Override
    public boolean shouldAllowInstantiationDeferral() {
        return true;
    }

    @Override
    public String toString() {
        if (isInstantiated()) {
            return "{" + getValue() + "}";
        } else {
            return "{" + Helper.getShortClassName(getClass()) + ": " + ToStringLocalization.buildMessage("not_instantiated", null) + "}";
        }
    }
}
