/*******************************************************************************
 * Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.internal.identitymaps;

import java.util.*;
import java.io.*;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.internal.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> Insert & retrieve objects from the cache.
 * <li> Allow retrieval and modification of writeLockValue for a cached object.
 * </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;
    
    public 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.
     */
    public 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.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    public abstract Enumeration elements();

    /**
     * Return the object cached in the identity map or null if it could not be found.
     * User API.
     */
    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 ClassDescriptor Descriptor type to be retrieved.
     * @return Map of Entity PKs associated to the Entities that were retrieved
     * @throws QueryException
     */
    public Map<Object, Object> getAllFromIdentityMapWithEntityPK(Object[] pkList, ClassDescriptor descriptor, AbstractSession session){
        HashMap<Object, Object> map = new HashMap<Object, Object>();
        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 ClassDescriptor Descriptor type to be retrieved.
     * @return Map of Entity PKs associated to the Entities that were retrieved
     * @throws QueryException
     */
    public Map<Object, CacheKey> getAllCacheKeysFromIdentityMapWithEntityPK(Object[] pkList, ClassDescriptor descriptor, AbstractSession session){
        HashMap<Object, CacheKey> map = new HashMap<Object, CacheKey>();
        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.
     */
    public abstract CacheKey getCacheKey(Object primaryKey, boolean forMerge);

    /**
     * Get the cache key (with object) for the primary key.
     */
    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 getDefaultIdentityMapClass() {
        return ClassConstants.SoftCacheWeakIdentityMap_Class;
    }

    /**
     * @return The maxSize for the IdentityMap (NOTE: some subclasses may use this differently).
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    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.
     */
    public Object remove(Object primaryKey, Object object) {
        CacheKey key = getCacheKeyForLock(primaryKey);
        return remove(key);
    }

    /**
     * Remove the CacheKey from the map.
     */
    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.
     */
    public void updateMaxSize(int maxSize) {
        setMaxSize(maxSize);
    }
    
    /**
     * Return the class that this is the map for.
     */
    public ClassDescriptor getDescriptor() {
        return descriptor;
    }
    
    /**
     * Return the class that this is the map for.
     */
    public Class getDescriptorClass() {
        if (descriptor == null) {
            return null;
        }
        return descriptor.getJavaClass();
    }
    
    /**
     * Set the descriptor that this is the map for.
     */
    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.
     */
    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.
     */
    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();
        }
    }

    public String toString() {
        return Helper.getShortClassName(getClass()) + "[" + getSize() + "]";
    }
}
