package eu.dnetlib.data.collective.manager.utils;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.ws.WebServiceFeature;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eu.dnetlib.common.utils.EprUtils;

/**
 * The purpose of this class is a temporary surrogate for the HNM and DynamicServiceLocator.
 * It registers service resources and returns them in a round-robin fashion.
 * @author jochen
 *
 * @param <T> type of worker service
 */
public class ServiceRegistry<T> {

	private static final Log log = LogFactory.getLog(ServiceRegistry.class);
	private List<String> serviceList;
	private Map<String, String> serviceMap;
	private Class<T> clazz;

	public ServiceRegistry() {
		this.serviceList = new LinkedList<String>();
		this.serviceMap = new LinkedHashMap<String, String>();
	}
		
	public boolean add(String id, String uri){
		serviceList.add(id);
		serviceMap.put(id, uri);
		log.debug("added Service; number of registered Services now: " + serviceList.size());
		return true;
	}
	
	public boolean remove(String id){
		if (serviceMap.containsKey(id)){
			serviceList.remove(id);
			serviceMap.remove(id);
			log.debug("removed Service; number of registered Services now: " + serviceList.size());
			return true;
		}
		return false;
	}
	
	/**
	 * retrieve the next available service represented by its resource-id
	 * @return the resource-id or null if no more services are available
	 */
	public String next(){
		if (serviceList.isEmpty()) return null;
		String id = serviceList.get(0);
		Collections.rotate(serviceList, -1);
		return id;		
	}
	
	public int size(){
		return serviceList.size();
	}
		
	public T getService(String id){
		if (!serviceMap.containsKey(id)){
			log.warn("unknown id: " + id);
			return null;
		}
		String wsdlUri = serviceMap.get(id);
		String address = wsdlUri.substring(0, wsdlUri.indexOf("?"));
		
		
		try {
			return EprUtils.buildW3CEPR(address, wsdlUri).getPort(clazz, new WebServiceFeature[]{} );
		} catch (ParserConfigurationException e) {
			throw new IllegalStateException(e);
		}
	}
	
	public Class<T> getClazz() {
		return clazz;
	}

	public void setClazz(Class<T> clazz) {
		this.clazz = clazz;
	}

}
