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

import java.io.Serializable;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.sessions.AbstractSession;

/**
 * <p><b>Purpose</b>: Caches objects, and allows their retrieval  by their primary key.
 * <p><b>Responsibilities</b>:
 * <ul>
 * <li> Store CacheKeys containing objects and possibly writeLockValues.</li>
 * <li> Insert &amp; retrieve objects from the cache.</li>
 * <li> Allow retrieval and modification of writeLockValue for a cached object.</li>
 * </ul>
 * @see CacheKey
 * @since TOPLink/Java 1.0
 */
public abstract class AbstractIdentityMap implements IdentityMap, Serializable, Cloneable {

    /** The initial or maximum size of the cache depending upon the concrete implementation. */
    protected int maxSize;

    /** PERF: Store the descriptor to allow lastAccessed cache lookup optimization. */
    protected transient ClassDescriptor descriptor;

    /** Is this identity map within an IsolatedClientSession */
    protected boolean isIsolated;

    /** Session that the map is on */
    protected AbstractSession session;

    protected AbstractIdentityMap(){
    }

    /**
     * Instantiate an new IdentityMap with it's maximum size.<p>
     * <b>NOTE</b>: Subclasses may provide different behavior for maxSize.
     * @param size is the maximum size to be allocated for the receiver.
     */
    protected AbstractIdentityMap(int size, ClassDescriptor descriptor, AbstractSession session, boolean isolated) {
        this.maxSize = size;
        this.descriptor = descriptor;
        this.isIsolated = isolated;
        this.session = session;
    }

    /**
     * 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) {
        CacheKey cacheKey = getCacheKey(primaryKey, false);
        if (cacheKey == null) {
            // Create and lock a new cacheKey.
            CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
            newCacheKey.acquireDeferredLock();
            // PERF: To avoid synchronization, getIfAbsentPut is used.
            cacheKey = putCacheKeyIfAbsent(newCacheKey);
            // Return if the newCacheKey was put as it was already locked, otherwise must still lock it.
            if (cacheKey == null) {
                return newCacheKey;
            } else {
                newCacheKey.releaseDeferredLock();
            }
        }
        // Acquire a lock on the cache key.
        cacheKey.acquireDeferredLock();
        return cacheKey;
    }

    /**
     * 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) {
        CacheKey cacheKey = getCacheKey(primaryKey, forMerge);
        if (cacheKey == null) {
            // Create and lock a new cacheKey.
            CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
            newCacheKey.acquire(forMerge);
            // PERF: To avoid synchronization, getIfAbsentPut is used.
            cacheKey = putCacheKeyIfAbsent(newCacheKey);
            // Return if the newCacheKey was put as it was already locked, otherwise must still lock it.
            if (cacheKey == null) {
                return newCacheKey;
            } else {
                newCacheKey.release();
            }
        }
        // Acquire a lock on the cache key.
        cacheKey.acquire();
        return cacheKey;
    }

    /**
     * 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 cacheKey = getCacheKey(primaryKey, forMerge);
        if (cacheKey == null) {
            // Create and lock a new cacheKey.
            CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
            newCacheKey.acquire(forMerge);
            // PERF: To avoid synchronization, getIfAbsentPut is used.
            cacheKey = putCacheKeyIfAbsent(newCacheKey);
            // Return if the newCacheKey was put as already lock, otherwise must still lock.
            if (cacheKey == null) {
                return newCacheKey;
            } else {
                newCacheKey.release();
            }
        }
        // Acquire a lock on the cache key.
        // Return null if already locked.
        if (!cacheKey.acquireNoWait(forMerge)) {
            return null;
        }
        return cacheKey;
    }

    /**
     * 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 cacheKey = getCacheKey(primaryKey, forMerge);
        if (cacheKey == null) {
            // Create and lock a new cacheKey.
            CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
            newCacheKey.acquire(forMerge);
            // PERF: To avoid synchronization, getIfAbsentPut is used.
            cacheKey = putCacheKeyIfAbsent(newCacheKey);
            // Return if the newCacheKey was put as already lock, otherwise must still lock.
            if (cacheKey == null) {
                return newCacheKey;
            } else {
                newCacheKey.release();
            }
        }
        // Acquire a lock on the cache key.
        // Return null if already locked.
        if (!cacheKey.acquireWithWait(forMerge, wait)) {
            return null;
        }
        return cacheKey;
    }

    /**
     * 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) {
        CacheKey cacheKey = getCacheKey(primaryKey, false);
        if (cacheKey == null) {
            CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
            // Lock new cacheKey.
            newCacheKey.acquireReadLock();
            // Create one but not put it in the cache, as we are only reading
            // and should not be writing to the identitymap.
            return newCacheKey;
        }
        // Acquire a lock on the cache key.
        // Return null if already locked.
        cacheKey.acquireReadLock();
        return cacheKey;
    }

    /**
     * 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 cacheKey = getCacheKey(primaryKey, false);
        if (cacheKey == null) {
            CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
            // Lock new cacheKey.
            newCacheKey.acquireReadLock();
            // Create one but not put it in the cache, as we are only reading
            // and should not be writing to the identitymap.
            return newCacheKey;
        }
        // Acquire a lock on the cache key.
        // Return null if already locked.
        if (!cacheKey.acquireReadLockNoWait()) {
            return null;
        }
        return cacheKey;
    }

    /**
     * Add all locked CacheKeys to the map grouped by thread.
     * Used to print all the locks in the identity map.
     */
    @Override
    public abstract void collectLocks(HashMap 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 Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException exception) {
            throw new InternalError(exception.toString());
        }
    }

    /**
     * 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 getCacheKeyWithReadLock(primaryKey) != null;
    }

    /**
     * Create the correct type of CacheKey for this map.
     */
    public CacheKey createCacheKey(Object primaryKey, Object object, Object writeLockValue, long readTime) {
        return new CacheKey(primaryKey, object, writeLockValue, readTime, this.isIsolated);
    }

    /**
     * Allow for the cache to be iterated on.
     */
    @Override
    public abstract Enumeration 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) {
        CacheKey cacheKey = getCacheKeyWithReadLock(primaryKey);
        if (cacheKey == null) {
            return null;
        }
        return cacheKey.getObject();
    }

    /**
     * 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 Map<Object, Object> getAllFromIdentityMapWithEntityPK(Object[] pkList, ClassDescriptor descriptor, AbstractSession session){
        HashMap<Object, Object> map = new HashMap<>();
        CacheKey cachedObject = null;
        long currentTime = System.currentTimeMillis();
        for (Object pk : pkList){
            cachedObject = getCacheKey(pk, false);
            if ((cachedObject != null && cachedObject.getObject() != null && !descriptor.getCacheInvalidationPolicy().isInvalidated(cachedObject, currentTime))){
                map.put(pk, cachedObject.getObject());
            }
        }
        return map;
    }

    /**
     * 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 Map<Object, CacheKey> getAllCacheKeysFromIdentityMapWithEntityPK(Object[] pkList, ClassDescriptor descriptor, AbstractSession session){
        HashMap<Object, CacheKey> map = new HashMap<>();
        CacheKey cachedObject = null;
        long currentTime = System.currentTimeMillis();
        for (Object pk : pkList){
            cachedObject = getCacheKey(pk, false);
            if ((cachedObject != null && cachedObject.getObject() != null && !descriptor.getCacheInvalidationPolicy().isInvalidated(cachedObject, currentTime))){
                map.put(pk, cachedObject);
            }
        }
        return map;
    }

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

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

    /**
     * Return the CacheKey (with object) matching the searchKey.
     * If the CacheKey is missing then put the searchKey in the map.
     * The searchKey should have already been locked.
     */
    protected abstract CacheKey putCacheKeyIfAbsent(CacheKey cacheKey);

    /**
     * Get the cache key (with object) for the primary key with read lock.
     */
    protected CacheKey getCacheKeyWithReadLock(Object primaryKey) {
        CacheKey key = getCacheKey(primaryKey, false);
        if (key != null) {
            key.checkReadLock();
        }
        return key;
    }

    /**
     * Returns the class which should be used as an identity map in a descriptor by default.
     */
    public static Class<? extends IdentityMap> getDefaultIdentityMapClass() {
        return ClassConstants.SoftCacheWeakIdentityMap_Class;
    }

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

    /**
     * Return the number of CacheKeys in the IdentityMap.
     * This may contain weak referenced objects that have been garbage collected.
     */
    @Override
    public abstract int 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 abstract int getSize(Class<?> myClass, boolean recurse);

    /**
     * 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) {
        CacheKey cacheKey = getCacheKeyWithReadLock(primaryKey);
        if (cacheKey == null) {
            return null;
        } else {
            return cacheKey.getWrapper();
        }
    }

    /**
     * Get the write lock value from the cache key associated to the primarykey.
     * User API.
     */
    @Override
    public Object getWriteLockValue(Object primaryKey) {
        CacheKey cacheKey = getCacheKeyWithReadLock(primaryKey);
        if (cacheKey == null) {
            return null;
        } else {
            return cacheKey.getWriteLockValue();
        }
    }

    /**
     * Allow for the CacheKeys to be iterated on.
     */
    @Override
    public abstract Enumeration keys();

    /**
     * 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 abstract CacheKey put(Object primaryKey, Object object, Object writeLockValue, long readTime);

    /**
     * This method may be called during initialize all identity maps.  It allows the identity map
     * or interceptor the opportunity to release any resources before being thrown away.
     */
    @Override
    public void release(){
        //no-op
    }

    /**
     * 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) {
        CacheKey key = getCacheKeyForLock(primaryKey);
        return remove(key);
    }

    /**
     * Remove the CacheKey from the map.
     */
    @Override
    public abstract Object remove(CacheKey cacheKey);

    /**
     * Set the maximum size for the receiver.
     * @param size is the new maximum size.
     */
    protected synchronized void setMaxSize(int size) {
        maxSize = size;
    }

    /**
     * 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) {
        setMaxSize(maxSize);
    }

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

    /**
     * Return the class that this is the map for.
     */
    @Override
    public Class<?> getDescriptorClass() {
        if (descriptor == null) {
            return null;
        }
        return descriptor.getJavaClass();
    }

    /**
     * Set the descriptor that this is the map for.
     */
    @Override
    public void setDescriptor(ClassDescriptor descriptor) {
        this.descriptor = 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) {
        CacheKey cacheKey = getCacheKeyForLock(primaryKey);
        if (cacheKey != null) {
            cacheKey.setWrapper(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) {
        CacheKey cacheKey = getCacheKeyForLock(primaryKey);
        if (cacheKey != null) {
            //lock/release the cache key during the lock value updating
            cacheKey.acquire();
            cacheKey.setWriteLockValue(writeLockValue);
            cacheKey.release();
        }
    }

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