/**
 * 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 org.apache.jena.atlas.lib;

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A key {@literal ->} value 'map' which reference counts entries.  
 * 
 * <p>
 *   The same (key,value) pair can be added to the map several times and then 
 *   removed several times.  A reference count is incremented for each addition
 *   and, provided the count is greater than 0, decremented on removal.
 * <p>
 * 
 * <p>
 *   The pair is removed from the map when a remove decrements the reference count to 0.
 * </p>
 * 
 * <p>
 *   This class is thread safe.
 * </p>
 * 
 * @param <K>
 * @param <T>
 */
public class RefCountingMap<K, T> {
	
	/*
	 * Uses CountedRef instances which are pairs of an integer and
	 * and a reference.  These instances are immutable - a new instance
	 * is created on each increment/decrement operation.  This could
	 * result in churn in the garbage collector under heavy use.
	 */
	protected Map<K, CountedRef<T>> map = new ConcurrentHashMap<>() ;
	   
    public RefCountingMap() {}   

    public boolean contains(K key)         { return map.containsKey(key) ; }
    public Collection<K> keys()            { return map.keySet() ; }
    public int size()                      { return map.size() ; }
    public boolean isEmpty()               { return map.isEmpty() ; }

    /** Clear the map of all keys regardless of reference counts. */
    public void clear()                    { map.clear() ; }
    
	public Set<K> keySet()                 { return map.keySet(); }
	public boolean containsKey(Object key) { return map.containsKey(key); }
    
	/**
	 * Add a key value pair to the map.
	 * 
	 * <p>
	 *   if there is no entry in the map for the key, then a key value pair is added
	 *   to the map with a reference count of 1.
	 * </p>
	 * 
	 * <p>
	 *   If there is already an entry in the map for the same key and value,
	 *   the reference count for that entry is incremented.
	 * </p>
	 * 
	 * <p>
	 *   if there is an entry in the map for the key, but with a different value,
	 *   then that entry is replaced with a new entry for the key and value with
	 *   a reference count of 1.
	 * </p>
	 * 
	 * @param key
	 * @param value
	 */
    public void add(K key, T value) {
    	// map.compute is atomic
    	map.compute(key,
    			(k, v) -> {
    				int refCount = 1 ;
    				if (v != null && ( v.getRef().equals(value) ) ) {
    					refCount = v.getCount() + 1;
    				}
    				return new CountedRef<>(value, refCount );
    			});
    }
    
    /**
     * Decrement the reference count for a key, and remove the corresponding entry from the map
     * if the result is 0.
     * 
     * <p>
     *   Do nothing if there is no entry in the map corresponding to the key.
     * </p>
     * @param key
     */
    public void remove(K key) {
    	// map.compute is atomic
    	map.compute(key, 
    			(k, v) -> {
    				if (v == null)
    					return null ;
    				int refCount = v.getCount() - 1 ;
    				if ( refCount == 0 )
    				    return null ;
    				else
    				    return new CountedRef<>(v.getRef(), refCount);
    			});
    }
    
    /**
     * Remove the entry corresponding to the key from the map completely.
     * 
     * <p>
     *   This method ignores the reference count.
     * </p>
     * 
     * @param key
     */
    public void removeAll(K key) {
    	map.remove(key);
    }

    /**
     * Return the reference count for the entry corresponding to a key in the map.
     * 
     * <p>
     *   Returns 0 if there is no entry in the map corresponding to the key.
     * </p>
     * @param key
     * @return the reference count for the entry corresponding to key in the map,
     *         or 0 if there is no corresponding entry.
     */
    public int refCount(K key) { 
    	CountedRef<T> ref = map.get(key);
    	if (ref == null) {
    		return 0 ;
    	} else {
    		return ref.getCount();
    	}
    }

    /**
     * Return the value associated with a key in the map.
     * 
     * @param key
     * @return the value associated with the key, or null if there is no such value.
     */
	public T get(Object key) {
		CountedRef<T> ref = map.get(key);
		if ( ref == null ) return null ;
		return ref.getRef();
	}

	/*
	 * An immutable pair of an integer count and an object reference
	 */
    class CountedRef<R> {
  	    final int refCount;
	    final R    ref;
	
	    CountedRef(R ref, int refCount) {
	    	this.refCount = refCount;
	    	this.ref = ref;
	    }
	
	    int getCount()  { return refCount ; }
	    R   getRef()    { return ref; }
    }
}
