/*
 * 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:
//     Gordon Yorke - Initial Feature development
//     12/14/2017-3.0 Tomas Kraus
//       - 522635: ConcurrentModificationException when triggering lazy load from conforming query
package org.eclipse.persistence.sessions.interceptors;

import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.identitymaps.IdentityMap;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;


/**
 * <p>
 * <b>Purpose</b>: Define a class through which Cache access can be
 * intercepted.
 * <p>
 * <b>Description</b>: EclipseLink makes extensive use of caching
 * functionality. This class provides the mechanism for intercepting the cache
 * access. Once intercepted applications can allow the process to continue by
 * calling the method on the class attribute targetIdentityMap as described in
 * the API javadocs or redirect the process entirely. * As with IdentityMaps an
 * entire class inheritance hierarchy will share the same interceptor.
 * <p>
 * To implement a CacheInterceptor users should subclass this class implementing
 * those methods they wish to intercept.
 * <p>
 * <b>Configuration</b>: Interceptors may be added to a session by using a
 * Session or Descriptor customizer to set the class name of the interceptor on
 * the target ClassDescriptor through the method
 * setCacheInterceptorClass(Class).
 */
public abstract class CacheInterceptor implements IdentityMap {
    /**
     * This attribute stores the actual IdentityMap as configured by the user.
     */
    protected IdentityMap targetIdentityMap;

    protected AbstractSession interceptedSession;

    protected CacheInterceptor(IdentityMap targetIdentityMap, AbstractSession interceptedSession){
        this.targetIdentityMap = targetIdentityMap;
        this.interceptedSession = interceptedSession;
    }
    /**
     * Acquire a deferred lock on the object.
     * This is used while reading if the object has relationships without indirection.
     * This first thread will get an active lock.
     * Other threads will get deferred locks, all threads will wait until all other threads are complete before releasing their locks.
     */
    @Override
    public CacheKey acquireDeferredLock(Object primaryKey, boolean isCacheCheckComplete){
        return createCacheKeyInterceptor(this.targetIdentityMap.acquireDeferredLock(primaryKey, isCacheCheckComplete));
    }

    /**
     * Acquire an active lock on the object.
     * This is used by reading (when using indirection or no relationships) and by merge.
     */
    @Override
    public CacheKey acquireLock(Object primaryKey, boolean forMerge, boolean isCacheCheckComplete){
        return createCacheKeyInterceptor(this.targetIdentityMap.acquireLock(primaryKey, forMerge, isCacheCheckComplete));
    }

    /**
     * Acquire an active lock on the object, if not already locked.
     * This is used by merge for missing existing objects.
     */
    @Override
    public CacheKey acquireLockNoWait(Object primaryKey, boolean forMerge){
        CacheKey cacheKeyToBeWrapped = this.targetIdentityMap.acquireLockNoWait(primaryKey, forMerge);
        if (cacheKeyToBeWrapped != null){
            return createCacheKeyInterceptor(cacheKeyToBeWrapped);
        }
        return null;
    }

    /**
     * Acquire an active lock on the object, if not already locked.
     * This is used by merge for missing existing objects.
     */
    @Override
    public CacheKey acquireLockWithWait(Object primaryKey, boolean forMerge, int wait) {
        CacheKey cacheKeyToBeWrapped = this.targetIdentityMap.acquireLockWithWait(primaryKey, forMerge, wait);
        if (cacheKeyToBeWrapped != null) {
            return createCacheKeyInterceptor(cacheKeyToBeWrapped);
        }
        return null;
    }

    /**
     * Acquire a read lock on the object.
     * This is used by UnitOfWork cloning.
     * This will allow multiple users to read the same object but prevent writes to the object while the read lock is held.
     */
    @Override
    public CacheKey acquireReadLockOnCacheKey(Object primaryKey) {
        return createCacheKeyInterceptor(this.targetIdentityMap.acquireReadLockOnCacheKey(primaryKey));
    }

    /**
     * Acquire a read lock on the object, if not already locked.
     * This is used by UnitOfWork cloning.
     * This will allow multiple users to read the same object but prevent writes to the object while the read lock is held.
     */
    @Override
    public CacheKey acquireReadLockOnCacheKeyNoWait(Object primaryKey) {
        CacheKey cacheKeyToBeWrapped = this.targetIdentityMap.acquireReadLockOnCacheKeyNoWait(primaryKey);
        if (cacheKeyToBeWrapped != null){
            return createCacheKeyInterceptor(cacheKeyToBeWrapped);
        }
        return null;
    }

    /**
     * Add all locked CacheKeys to the map grouped by thread.
     * Used to print all the locks in the identity map.
     */
    @Override
    public void collectLocks(HashMap threadList) {
        this.targetIdentityMap.collectLocks(threadList);
    }

    /**
     * Clone the map and all of the CacheKeys.
     * This is used by UnitOfWork commitAndResumeOnFailure to avoid corrupting the cache during a failed commit.
     */
    @Override
    public abstract Object clone();

    /**
     * Return true if an CacheKey with the primary key is in the map.
     * User API.
     * @param primaryKey is the primary key for the object to search for.
     */
    @Override
    public boolean containsKey(Object primaryKey) {
        return this.targetIdentityMap.containsKey(primaryKey);
    }


    protected abstract CacheKeyInterceptor createCacheKeyInterceptor(CacheKey wrappedCacheKey);

    /**
     * Allow for the cache to be iterated on.  This method is only used during debugging when
     * validateCache() has been called to print out the contents of the cache.
     */
    @Override
    public Enumeration elements() {
        return this.targetIdentityMap.elements();
    }

    /**
     * Return the object cached in the identity map or null if it could not be found.
     * User API.
     */
    @Override
    public Object get(Object primaryKey){
        return this.targetIdentityMap.get(primaryKey);
    }

    /**
     * ADVANCED:
     * Using a list of Entity PK this method will attempt to bulk load the entire list from the cache.
     * In certain circumstances this can have large performance improvements over loading each item individually.
     * @param pkList List of Entity PKs to extract from the cache
     * @param descriptor Descriptor type to be retrieved.
     * @return Map of Entity PKs associated to the Entities that were retrieved
     */
    @Override
    public abstract Map<Object, Object> getAllFromIdentityMapWithEntityPK(Object[] pkList, ClassDescriptor descriptor, AbstractSession session);

    /**
     * ADVANCED:
     * Using a list of Entity PK this method will attempt to bulk load the entire list from the cache.
     * In certain circumstances this can have large performance improvements over loading each item individually.
     * @param pkList List of Entity PKs to extract from the cache
     * @param descriptor Descriptor type to be retrieved.
     * @return Map of Entity PKs associated to the Entities that were retrieved
     */
    @Override
    public abstract Map<Object, CacheKey> getAllCacheKeysFromIdentityMapWithEntityPK(Object[] pkList, ClassDescriptor descriptor, AbstractSession session);

    /**
     * Get the cache key (with object) for the primary key.
     */
    @Override
    public CacheKey getCacheKey(Object primaryKey, boolean forMerge) {
        return this.targetIdentityMap.getCacheKey(primaryKey, forMerge);
    }

    /**
     * Get the cache key (with object) for the primary key.
     */
    @Override
    public CacheKey getCacheKeyForLock(Object primaryKey) {
        return this.targetIdentityMap.getCacheKeyForLock(primaryKey);
    }

    /**
     * Return the descriptor that this is the map for.
     */
    @Override
    public ClassDescriptor getDescriptor() {
        return this.targetIdentityMap.getDescriptor();
    }

    /**
     * Return the class that this is the map for.
     */
    @Override
    public Class getDescriptorClass() {
        return this.targetIdentityMap.getDescriptorClass();
    }

    /**
     * @return The maxSize for the IdentityMap (NOTE: some subclasses may use this differently).
     */
    @Override
    public int getMaxSize() {
        return this.targetIdentityMap.getMaxSize();
    }

    /**
     * Return the number of CacheKeys in the IdentityMap.
     * This may contain weak referenced objects that have been garbage collected.
     */
    @Override
    public int getSize() {
        return this.targetIdentityMap.getSize();
    }

    /**
     * Return the number of actual objects of type myClass in the IdentityMap.
     * Recurse = true will include subclasses of myClass in the count.
     */
    @Override
    public int getSize(Class myClass, boolean recurse) {
        return this.targetIdentityMap.getSize(myClass, recurse);
    }

    /**
     * Return the instance of the IdentityMap that this intercpetor is wrapping.  Any call that
     * is to be passed on to the underlying EclipseLink cache should be passed to this IdentityMap.
     */
    public IdentityMap getTargetIdenttyMap() {
        return this.targetIdentityMap;
    }

    /**
     * Get the wrapper object from the cache key associated with the given primary key,
     * this is used for EJB2.
     */
    @Override
    public Object getWrapper(Object primaryKey) {
        return this.targetIdentityMap.getWrapper(primaryKey);
    }

    /**
     * Get the write lock value from the cache key associated to the primarykey.
     * User API.
     */
    @Override
    public Object getWriteLockValue(Object primaryKey) {
        return this.targetIdentityMap.getWriteLockValue(primaryKey);
    }

    /**
     * Allow for the {@link CacheKey} elements to be iterated.
     * {@link CacheKey} {@link Collection} is reused so this iteration may not be thread safe.
     *
     * @return {@link Enumeration} of {@link CacheKey} instances.
     */
    @Override
    public Enumeration<CacheKey> keys() {
        return this.targetIdentityMap.keys();
    }

    /**
     * Allow for the {@link CacheKey} elements to be iterated.
     * Clone of {@link CacheKey} {@link Collection} is returned so this iteration should
     * be thread safe.
     *
     * @return {@link Enumeration} with clone of the {@link CacheKey} {@link Collection}
     */
    @Override
    public Enumeration<CacheKey> cloneKeys() {
        return this.targetIdentityMap.cloneKeys();
    }

    /**
     * Allow for the {@link CacheKey} elements to be iterated.
     * {@link CacheKey} {@link Collection} is reused so this iteration may not be thread safe.
     *
     * @param checkReadLocks value of {@code true} if read lock on the {@link CacheKey}
     *        instances should be checked or {@code false} otherwise
     * @return {@link Enumeration} of {@link CacheKey} instances.
     */
    @Override
    public Enumeration<CacheKey> keys(boolean checkReadLocks) {
        return this.targetIdentityMap.keys(checkReadLocks);
    }

    /**
     * Notify the cache that a lazy relationship has been triggered in the object
     * and the cache may need to be updated
     */
    @Override
    public void lazyRelationshipLoaded(Object rootEntity, ValueHolderInterface valueHolder, ForeignReferenceMapping mapping){
        this.targetIdentityMap.lazyRelationshipLoaded(rootEntity, valueHolder, mapping);
    }

    /**
     * Store the object in the cache at its primary key.
     * This is used by InsertObjectQuery, typically into the UnitOfWork identity map.
     * Merge and reads do not use put, but acquireLock.
     * Also an advanced (very) user API.
     * @param primaryKey is the primary key for the object.
     * @param object is the domain object to cache.
     * @param writeLockValue is the current write lock value of object, if null the version is ignored.
     */
    @Override
    public CacheKey put(Object primaryKey, Object object, Object writeLockValue, long readTime) {
        return this.targetIdentityMap.put(primaryKey, object, writeLockValue, readTime);
    }

    /**
     * Remove the CacheKey with the primaryKey from the map.
     * This is used by DeleteObjectQuery and merge.
     * This is also an advanced (very) user API.
     */
    @Override
    public Object remove(Object primaryKey, Object object) {
        return this.targetIdentityMap.remove(primaryKey, object);
    }

    /**
     * Remove the CacheKey from the map.
     */
    @Override
    public Object remove(CacheKey cacheKey) {
        if (cacheKey.isWrapper()){
            return this.targetIdentityMap.remove(cacheKey.getWrappedCacheKey());
        }
        return this.targetIdentityMap.remove(cacheKey);
    }

    /**
     * This method will be used to update the max cache size, any objects exceeding the max cache size will
     * be remove from the cache. Please note that this does not remove the object from the identityMap, except in
     * the case of the CacheIdentityMap.
     */
    @Override
    public void updateMaxSize(int maxSize){
        this.targetIdentityMap.updateMaxSize(maxSize);
    }

    /**
     * Set the descriptor that this is the map for.
     */
    @Override
    public void setDescriptor(ClassDescriptor descriptor) {
        this.targetIdentityMap.setDescriptor(descriptor);
    }

    /**
     * Update the wrapper object in the CacheKey associated with the given primaryKey,
     * this is used for EJB2.
     */
    @Override
    public void setWrapper(Object primaryKey, Object wrapper) {
        this.targetIdentityMap.setWrapper(primaryKey, wrapper);
    }

    /**
     * Update the write lock value of the CacheKey associated with the given primaryKey.
     * This is used by UpdateObjectQuery, and is also an advanced (very) user API.
     */
    @Override
    public void setWriteLockValue(Object primaryKey, Object writeLockValue) {
        this.targetIdentityMap.setWriteLockValue(primaryKey, writeLockValue);
    }

    @Override
    public String toString() {
        return Helper.getShortClassName("Intercepted " + this.targetIdentityMap.getClass()) + "[" + getSize() + "]";
    }
}
