/**
 * Copyright 2008-2009 DRIVER PROJECT (ICM UW)
 * Original author: Marek Horst
 *
 * Licensed 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 eu.dnetlib.data.index.ws.bbq;

import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;
import org.apache.log4j.Logger;

/**
 * Simple, bidiMap based IBBQMappingsContainer implementation.
 * @author Marek Horst
 * @version 0.7.6
 *
 */
public class SimpleBBQMappingsContainer implements IBBQMappingsContainer {

	private static final Logger log = Logger.getLogger(SimpleBBQMappingsContainer.class);
	
//	TODO consider using ReadWriteLock
	private BidiMap collNameToBBQueryMap = new DualHashBidiMap();
	
	
	/* (non-Javadoc)
	 * @see eu.dnetlib.data.index.ws.bbq.IBBQMappingsContainer#getCollectionName(java.lang.String)
	 */
	public String getCollectionName(String bbQuery) {
		if (bbQuery==null)
			return null;
		return getKey(bbQuery);
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.data.index.ws.bbq.IBBQMappingsContainer#removeMapping(java.lang.String)
	 */
	public String removeMapping(String collectionName) {
		if (collectionName==null)
			return null;
		return remove(collectionName);
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.data.index.ws.bbq.IBBQMappingsContainer#setMapping(java.lang.String, java.lang.String)
	 */
	public boolean setMapping(String collectionName, String bbQuery) {
		if (collectionName==null || bbQuery==null) {
			log.warn("Cannot store null values! " + 
					"Got collectionName: " + collectionName + ", bbQuery: " + bbQuery);
			return false;
		} else {
			boolean result = false;
			String storedBBQuery = getValue(collectionName);
			if (storedBBQuery!=null && !bbQuery.equals(storedBBQuery))
				result = true;
			log.debug("storing mapping for collection: " + collectionName +
					" and bbq: " + bbQuery);
			put(collectionName, bbQuery);
			return result;
		}
	}

	/**
	 * Returns value for given key. Synchronized access.
	 * @param key
	 * @return value for given key
	 */
	private synchronized String getValue(String key) {
		return (String) collNameToBBQueryMap.get(key);
	}
	
	/**
	 * Returns key for given value. Synchronized access.
	 * @param value
	 * @return key for given value
	 */
	private synchronized String getKey(String value) {
		return (String) collNameToBBQueryMap.getKey(value);
	}
	
	/**
	 * Stores key and value pair. Synchronized access.
	 * @param key
	 * @param value
	 */
	private synchronized void put(String key, String value) {
		collNameToBBQueryMap.put(key, value);
	}
	
	/**
	 * Removes entry for given key value.
	 * Returns removed value or null if no entry found for given key.
	 * @param key
	 * @return removed value or null if no entry found for given key
	 */
	private synchronized String remove(String key) {
		return (String) collNameToBBQueryMap.remove(key);
	}

}
