/*
 * 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 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.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.exceptions.*;

/**
 * BatchValueHolder is used by the mappings that use indirection when using query optimization (batch reading).
 * This value holder is different from QueryBasedValueHolder in that its value must be extracted from one of the
 * results return by the query, not the entire result.
 * The query is also shared by all other value holders within the batch and it must be ensured that the query is only
 * executed once.  Concurrency must also be maintained across all of the value holders in the batch.
 */
public class BatchValueHolder<T> extends QueryBasedValueHolder<T> {
    protected transient ForeignReferenceMapping mapping;
    protected transient ObjectLevelReadQuery originalQuery;
    protected transient CacheKey parentCacheKey;

    /**
     * Initialize the query-based value holder.
     * @param query The query that returns the object when executed.
     * @param row The row representation of the object.
     * @param mapping The mapping that is uses batch reading.
     */
    public BatchValueHolder(ReadQuery query, AbstractRecord row, ForeignReferenceMapping mapping, ObjectLevelReadQuery originalQuery, CacheKey parentCacheKey) {
        super(query, row, originalQuery.getSession());
        this.mapping = mapping;
        this.originalQuery = originalQuery;
        this.parentCacheKey = parentCacheKey;
    }

    protected ForeignReferenceMapping getMapping() {
        return mapping;
    }

    /**
     * Instantiate the object by having the mapping extract its value from the query.
     * Concurrency must be maintained across all of the value holders,
     * since they all share the same query, the extractResultFromBatchQuery method must be synchronized.
     */
    @Override
    @SuppressWarnings({"unchecked"})
    protected T instantiate(AbstractSession session) throws EclipseLinkException {
        return (T) this.mapping.extractResultFromBatchQuery(this.query, this.parentCacheKey, this.row, session, this.originalQuery);
    }

    /**
     * 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: This method is not
     * thread-safe. It must be used in a synchronized manner.
     * The batch value holder must use a batch query relative to the unit of work,
     * as the batch is local to the unit of work.
     */
    @Override
    @SuppressWarnings({"unchecked"})
    public T instantiateForUnitOfWorkValueHolder(UnitOfWorkValueHolder<T> unitOfWorkValueHolder) {
        UnitOfWorkImpl unitOfWork = unitOfWorkValueHolder.getUnitOfWork();
        ReadQuery localQuery = unitOfWork.getBatchQueries().get(this.query);
        if (localQuery == null) {
            localQuery = (ReadQuery)this.query.clone();
            unitOfWork.getBatchQueries().put(this.query, localQuery);
        }
        return (T) this.mapping.extractResultFromBatchQuery(localQuery, this.parentCacheKey, this.row, unitOfWorkValueHolder.getUnitOfWork(), this.originalQuery);
    }

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

    /**
     * Reset all the fields that are not needed after instantiation.
     */
    @Override
    protected void resetFields() {
        super.resetFields();
        this.mapping = null;
        this.originalQuery = null;
    }

    protected void setMapping(ForeignReferenceMapping mapping) {
        this.mapping = mapping;
    }
}
