package cz.cuni.amis.pogamut.base.factory.guice;

import com.google.inject.Guice;
import com.google.inject.Injector;

import cz.cuni.amis.pogamut.base.agent.IAgent;
import cz.cuni.amis.pogamut.base.communication.connection.IWorldConnection;
import cz.cuni.amis.pogamut.base.communication.connection.IWorldConnectionAddress;
import cz.cuni.amis.pogamut.base.exceptions.PogamutException;
import cz.cuni.amis.pogamut.base.factory.IAgentFactory;

/**
 * Guice agent factory configured by an agent module that is specifying the bindings 
 * for respective interfaces.
 * 
 * @author Jimmy
 *
 * @param <ADDRESS>
 */
public class GuiceAgentFactory<ADDRESS extends IWorldConnectionAddress> implements IAgentFactory<ADDRESS> {
	
	private Injector injector = null;
	
	private PogamutAgentModule agentModule = null;
	
	public GuiceAgentFactory(PogamutAgentModule agentModule) {
		this.agentModule = agentModule;
		if (this.agentModule == null) throw new IllegalArgumentException("'agentModule' can't be null");
	}
	
	protected Injector getInjector() {
		if (injector == null) injector = Guice.createInjector(agentModule);
		return injector;
	}
	
	protected PogamutAgentModule getAgentModule() {
		return agentModule;
	}

	@SuppressWarnings("unchecked")
	@Override
	public synchronized IAgent newAgent(ADDRESS address) throws PogamutException {
		getAgentModule().getAgentScope().clearScope();
		IAgent agent = getInjector().getInstance(IAgent.class);
		IWorldConnection<ADDRESS> connection = getInjector().getInstance(IWorldConnection.class);
		//connection.setLogMessages(true); 
		connection.connect(address);
		return agent;
	}
	
	

}
