/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package freemarker.cache;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;

/**
 * A cache storage that implements a two-level Most Recently Used cache. In the
 * first level, items are strongly referenced up to the specified maximum. When
 * the maximum is exceeded, the least recently used item is moved into the  
 * second level cache, where they are softly referenced, up to another 
 * specified maximum. When the second level maximum is also exceeded, the least 
 * recently used item is discarded altogether. This cache storage is a 
 * generalization of both {@link StrongCacheStorage} and 
 * {@link SoftCacheStorage} - the effect of both of them can be achieved by 
 * setting one maximum to zero and the other to the largest positive integer. 
 * On the other hand, if you wish to use this storage in a strong-only mode, or
 * in a soft-only mode, you might consider using {@link StrongCacheStorage} or
 * {@link SoftCacheStorage} instead, as they can be used by 
 * {@link TemplateCache} concurrently without any synchronization on a 5.0 or 
 * later JRE.
 *  
 * <p>This class is <em>NOT</em> thread-safe. If it's accessed from multiple
 * threads concurrently, proper synchronization must be provided by the callers.
 * Note that {@link TemplateCache}, the natural user of this class provides the
 * necessary synchronizations when it uses the class.
 * Also you might consider whether you need this sort of a mixed storage at all
 * in your solution, as in most cases SoftCacheStorage can also be sufficient. 
 * SoftCacheStorage will use Java soft references, and they already use access 
 * timestamps internally to bias the garbage collector against clearing 
 * recently used references, so you can get reasonably good (and 
 * memory-sensitive) most-recently-used caching through 
 * {@link SoftCacheStorage} as well.
 *
 * @see freemarker.template.Configuration#setCacheStorage(CacheStorage)
 */
public class MruCacheStorage implements CacheStorageWithGetSize {
    private final MruEntry strongHead = new MruEntry();
    private final MruEntry softHead = new MruEntry();
    {
        softHead.linkAfter(strongHead);
    }
    private final Map map = new HashMap();
    private final ReferenceQueue refQueue = new ReferenceQueue();
    private final int strongSizeLimit;
    private final int softSizeLimit;
    private int strongSize = 0;
    private int softSize = 0;
    
    /**
     * Creates a new MRU cache storage with specified maximum cache sizes. Each
     * cache size can vary between 0 and {@link Integer#MAX_VALUE}.
     * @param strongSizeLimit the maximum number of strongly referenced templates; when exceeded, the entry used
     *          the least recently will be moved into the soft cache.
     * @param softSizeLimit the maximum number of softly referenced templates; when exceeded, the entry used
     *          the least recently will be discarded.
     */
    public MruCacheStorage(int strongSizeLimit, int softSizeLimit) {
        if (strongSizeLimit < 0) throw new IllegalArgumentException("strongSizeLimit < 0");
        if (softSizeLimit < 0) throw new IllegalArgumentException("softSizeLimit < 0");
        this.strongSizeLimit = strongSizeLimit;
        this.softSizeLimit = softSizeLimit;
    }
    
    public Object get(Object key) {
        removeClearedReferences();
        MruEntry entry = (MruEntry) map.get(key);
        if (entry == null) {
            return null;
        }
        relinkEntryAfterStrongHead(entry, null);
        Object value = entry.getValue();
        if (value instanceof MruReference) {
            // This can only happen with strongSizeLimit == 0
            return ((MruReference) value).get();
        }
        return value;
    }

    public void put(Object key, Object value) {
        removeClearedReferences();
        MruEntry entry = (MruEntry) map.get(key);
        if (entry == null) {
            entry = new MruEntry(key, value);
            map.put(key, entry);
            linkAfterStrongHead(entry);
        } else {
            relinkEntryAfterStrongHead(entry, value);
        }
        
    }

    public void remove(Object key) {
        removeClearedReferences();
        removeInternal(key);
    }

    private void removeInternal(Object key) {
        MruEntry entry = (MruEntry) map.remove(key);
        if (entry != null) {
            unlinkEntryAndInspectIfSoft(entry);
        }
    }

    public void clear() {
        strongHead.makeHead();
        softHead.linkAfter(strongHead);
        map.clear();
        strongSize = softSize = 0;
        // Quick refQueue processing
        while (refQueue.poll() != null);
    }

    private void relinkEntryAfterStrongHead(MruEntry entry, Object newValue) {
        if (unlinkEntryAndInspectIfSoft(entry) && newValue == null) {
            // Turn soft reference into strong reference, unless is was cleared
            MruReference mref = (MruReference) entry.getValue();
            Object strongValue = mref.get();
            if (strongValue != null) {
                entry.setValue(strongValue);
                linkAfterStrongHead(entry);
            } else {
                map.remove(mref.getKey());
            }
        } else {
            if (newValue != null) {
                entry.setValue(newValue);
            }
            linkAfterStrongHead(entry);
        }
    }

    private void linkAfterStrongHead(MruEntry entry) {
        entry.linkAfter(strongHead);
        if (strongSize == strongSizeLimit) {
            // softHead.previous is LRU strong entry
            MruEntry lruStrong = softHead.getPrevious();
            // Attila: This is equaivalent to strongSizeLimit != 0
            // DD: But entry.linkAfter(strongHead) was just executed above, so
            //     lruStrong != strongHead is true even if strongSizeLimit == 0.
            if (lruStrong != strongHead) {
                lruStrong.unlink();
                if (softSizeLimit > 0) {
                    lruStrong.linkAfter(softHead);
                    lruStrong.setValue(new MruReference(lruStrong, refQueue));
                    if (softSize == softSizeLimit) {
                        // List is circular, so strongHead.previous is LRU soft entry
                        MruEntry lruSoft = strongHead.getPrevious();
                        lruSoft.unlink();
                        map.remove(lruSoft.getKey());
                    } else {
                        ++softSize;
                    }
                } else {
                    map.remove(lruStrong.getKey());
                }
            }
        } else {
            ++strongSize;
        }
    }

    private boolean unlinkEntryAndInspectIfSoft(MruEntry entry) {
        entry.unlink();
        if (entry.getValue() instanceof MruReference) {
            --softSize;
            return true;
        } else {
            --strongSize;
            return false;
        }
    }
    
    private void removeClearedReferences() {
        for (; ; ) {
            MruReference ref = (MruReference) refQueue.poll();
            if (ref == null) {
                break;
            }
            removeInternal(ref.getKey());
        }
    }
    
    /**
     * Returns the configured upper limit of the number of strong cache entries.
     *  
     * @since 2.3.21
     */
    public int getStrongSizeLimit() {
        return strongSizeLimit;
    }

    /**
     * Returns the configured upper limit of the number of soft cache entries.
     * 
     * @since 2.3.21
     */
    public int getSoftSizeLimit() {
        return softSizeLimit;
    }

    /**
     * Returns the <em>current</em> number of strong cache entries.
     *  
     * @see #getStrongSizeLimit()
     * @since 2.3.21
     */
    public int getStrongSize() {
        return strongSize;
    }

    /**
     * Returns a close approximation of the <em>current</em> number of soft cache entries.
     * 
     * @see #getSoftSizeLimit()
     * @since 2.3.21
     */
    public int getSoftSize() {
        removeClearedReferences();
        return softSize;
    }
    
    /**
     * Returns a close approximation of the current number of cache entries.
     * 
     * @see #getStrongSize()
     * @see #getSoftSize()
     * @since 2.3.21
     */
    public int getSize() {
        return getSoftSize() + getStrongSize();
    }

    private static final class MruEntry {
        private MruEntry prev;
        private MruEntry next;
        private final Object key;
        private Object value;
        
        /**
         * Used solely to construct the head element
         */
        MruEntry() {
            makeHead();
            key = value = null;
        }
        
        MruEntry(Object key, Object value) {
            this.key = key;
            this.value = value;
        }
        
        Object getKey() {
            return key;
        }
        
        Object getValue() {
            return value;
        }
        
        void setValue(Object value) {
            this.value = value;
        }

        MruEntry getPrevious() {
            return prev;
        }
        
        void linkAfter(MruEntry entry) {
            next = entry.next;
            entry.next = this;
            prev = entry;
            next.prev = this;
        }
        
        void unlink() {
            next.prev = prev;
            prev.next = next;
            prev = null;
            next = null;
        }
        
        void makeHead() {
            prev = next = this;
        }
    }
    
    private static class MruReference extends SoftReference {
        private final Object key;
        
        MruReference(MruEntry entry, ReferenceQueue queue) {
            super(entry.getValue(), queue);
            this.key = entry.getKey();
        }
        
        Object getKey() {
            return key;
        }
    }
    
    
}