/*
 * 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 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<T> implements WeavedAttributeValueHolderInterface<T>, Cloneable, Serializable {

    /** Stores the object after it is read from the database. */
    protected volatile T 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;

    /**
     * Default constructor.
     */
    protected DatabaseValueHolder() {
    }

    @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 T 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 T 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 T 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 T instantiateForUnitOfWorkValueHolder(UnitOfWorkValueHolder<T> 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(T 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(T 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) + "}";
        }
    }
}
