/**
 * 
 */
package eu.dnetlib.data.collective.manager;

import java.util.List;

import javax.annotation.Resource;


import eu.dnetlib.common.interfaces.nh.IBlackboardMessage.Action;
import eu.dnetlib.common.profile.ResourceDao;
import eu.dnetlib.data.collective.manager.nh.INotificationConsumer;
import eu.dnetlib.data.collective.manager.profile.AbstractInstance;
import eu.dnetlib.data.collective.manager.utils.InstanceRegistry;
import eu.dnetlib.data.information.DataSourceResolver;
import eu.dnetlib.data.information.MDStoreDataSinkSourceDescriptorGenerator;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.tools.ServiceLocator;

/**
 * @author jochen
 * @param <T> DNet-Service
 * @param <E> Instance DataStructure
 *
 */
public abstract class AbstractInstanceManager<E extends AbstractInstance> implements IInstanceManager<E>, INotificationConsumer {
	
	@Resource(name = "dataSourceResolver")
	protected DataSourceResolver dataSourceResolver;	
	
	@Resource(name = "lookupLocator")
	protected ServiceLocator<ISLookUpService> lookupLocator;
	
	@Resource(name = "resourceDao")
	protected ResourceDao resourceDao;
	
	@Resource(name = "instanceRegistry")
	protected InstanceRegistry<E> instanceRegistry;
	
	private MDStoreDataSinkSourceDescriptorGenerator dataSinkDescriptorGenerator = new MDStoreDataSinkSourceDescriptorGenerator();
	
	protected List<IInstanceListener<E>> listeners = new java.util.LinkedList<IInstanceListener<E>>();
	
	
	public abstract void addInstance(E aInstance);
	
	public abstract void updateInstance(E aInstance);
	
	public boolean startJobOnce(String aInstanceId, Action aAction){
		if (listeners.isEmpty()){
			return false;
		}		
		return listeners.get(0).fireOnce(instanceRegistry.getInstance(aInstanceId), aAction);
//		for (IInstanceListener<E> l:listeners){
//			l.fireOnce(aInstance, aAction);
//		}
	}
	
	public boolean cancelJobOnce(String aInstanceId, Action aAction){
		if (listeners.isEmpty()){
			return false;
		}
		return listeners.get(0).cancelOnce(instanceRegistry.getInstance(aInstanceId), aAction);
//		for (IInstanceListener<E> l:listeners){
//			l.cancelOnce(aInstance, aAction);
//		}		
	}

	public void setResourceDao(ResourceDao resourceDao) {
		this.resourceDao = resourceDao;
	}

	public ResourceDao getResourceDao() {
		return resourceDao;
	}
	
	
	protected String getGeneratedDataSinkDescriptor(String descriptorId, String storingType){
		return dataSinkDescriptorGenerator.generateDataSinkDescriptor(descriptorId, storingType);
	}

	public void setInstanceRegistry(InstanceRegistry<E> instanceRegistry) {
		this.instanceRegistry = instanceRegistry;
	}

	public InstanceRegistry<E> getInstanceRegistry() {
		return instanceRegistry;
	}

	public void setListeners(List<IInstanceListener<E>> listeners) {
		this.listeners = listeners;
	}

	public List<IInstanceListener<E>> getListeners() {
		return listeners;
	}

}
