/*
 * 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.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import freemarker.template.utility.UndeclaredThrowableException;

/**
 * Soft cache storage is a cache storage that uses {@link SoftReference} objects to hold the objects it was passed,
 * therefore allows the garbage collector to purge the cache when it determines that it wants to free up memory. This
 * class is thread-safe to the extent that its underlying map is. The parameterless constructor uses a thread-safe map
 * since 2.3.24 or Java 5.
 *
 * @see freemarker.template.Configuration#setCacheStorage(CacheStorage)
 */
public class SoftCacheStorage implements ConcurrentCacheStorage, CacheStorageWithGetSize {
    private static final Method atomicRemove = getAtomicRemoveMethod();
    
    private final ReferenceQueue queue = new ReferenceQueue();
    private final Map map;
    private final boolean concurrent;
    
    /**
     * Creates an instance that uses a {@link ConcurrentMap} internally.
     */
    public SoftCacheStorage() {
        this(new ConcurrentHashMap());
    }
    
    /**
     * Returns true if the underlying Map is a {@code ConcurrentMap}.
     */
    public boolean isConcurrent() {
        return concurrent;
    }
    
    public SoftCacheStorage(Map backingMap) {
        map = backingMap;
        this.concurrent = map instanceof ConcurrentMap;
    }
    
    public Object get(Object key) {
        processQueue();
        Reference ref = (Reference) map.get(key);
        return ref == null ? null : ref.get();
    }

    public void put(Object key, Object value) {
        processQueue();
        map.put(key, new SoftValueReference(key, value, queue));
    }

    public void remove(Object key) {
        processQueue();
        map.remove(key);
    }

    public void clear() {
        map.clear();
        processQueue();
    }
    
    /**
     * Returns a close approximation of the number of cache entries.
     * 
     * @since 2.3.21
     */
    public int getSize() {
        processQueue();
        return map.size();
    }

    private void processQueue() {
        for (; ; ) {
            SoftValueReference ref = (SoftValueReference) queue.poll();
            if (ref == null) {
                return;
            }
            Object key = ref.getKey();
            if (concurrent) {
                try {
                    atomicRemove.invoke(map, new Object[] { key, ref });
                } catch (IllegalAccessException e) {
                    throw new UndeclaredThrowableException(e);
                } catch (InvocationTargetException e) {
                    throw new UndeclaredThrowableException(e);
                }
            } else if (map.get(key) == ref) {
                map.remove(key);
            }
        }
    }

    private static final class SoftValueReference extends SoftReference {
        private final Object key;

        SoftValueReference(Object key, Object value, ReferenceQueue queue) {
            super(value, queue);
            this.key = key;
        }

        Object getKey() {
            return key;
        }
    }
    
    private static Method getAtomicRemoveMethod() {
        try {
            return Class.forName("java.util.concurrent.ConcurrentMap").getMethod("remove", new Class[] { Object.class, Object.class });
        } catch (ClassNotFoundException e) {
            return null;
        } catch (NoSuchMethodException e) {
            throw new UndeclaredThrowableException(e);
        }
    }
}