package com.github.aureliano.evtbridge.core.register;

import java.util.HashMap;
import java.util.Map;

import com.github.aureliano.evtbridge.common.exception.EventBridgeException;
import com.github.aureliano.evtbridge.common.helper.ReflectionHelper;
import com.github.aureliano.evtbridge.common.helper.StringHelper;
import com.github.aureliano.evtbridge.core.agent.IAgent;
import com.github.aureliano.evtbridge.core.config.IConfiguration;
import com.github.aureliano.evtbridge.core.config.IConfigurationConverter;

public final class ApiServiceRegistrator {

	private static ApiServiceRegistrator instance;
	
	private Map<String, ServiceRegistration> registrations;
	
	private ApiServiceRegistrator() {
		this.registrations = new HashMap<String, ServiceRegistration>();
	}
	
	public void registrate(Class<? extends IConfiguration> configuration, Class<? extends IAgent> executor) {
		this.registrate(configuration, executor, null);
	}
	
	public void registrate(Class<? extends IConfiguration> configuration, Class<? extends IAgent> executor, Class<? extends IConfigurationConverter<?>> converter) {
		this.registrate(this.createService(configuration, executor, converter));
	}
	
	public void registrate(ServiceRegistration registration) {
		if (StringHelper.isEmpty(registration.getId())) {
			if (registration.getConfiguration() != null) {
				IConfiguration configuration = (IConfiguration) ReflectionHelper.newInstance(registration.getConfiguration());
				registration.withId(configuration.id());
			} else {
				throw new EventBridgeException("Service registration expected to get a valid id but got an empty value.");
			}
		}
		
		this.registrations.put(registration.getId(), registration);
	}
	
	public IAgent createAgent(IConfiguration configuration) {
		ServiceRegistration registration = this.registrations.get(configuration.id());
		
		if ((registration == null) || (registration.getAgent() == null)) {
			throw new EventBridgeException("There isn't an executor (reader/writer) registered with ID " + configuration.id());
		}
		
		IAgent executor = (IAgent) ReflectionHelper.newInstance(registration.getAgent());
		return executor.withConfiguration(configuration);
	}
	
	public IConfigurationConverter<?> createConverter(String id) {
		ServiceRegistration registration = this.registrations.get(id);
		if (registration != null) {
			return (IConfigurationConverter<?>) ReflectionHelper.newInstance(registration.getConverter());
		}
		
		registration = this.registrations.get(id.toUpperCase());
		if (registration != null) {
			return (IConfigurationConverter<?>) ReflectionHelper.newInstance(registration.getConverter());
		}
		
		registration = this.registrations.get(id.toLowerCase());
		if (registration != null) {
			return (IConfigurationConverter<?>) ReflectionHelper.newInstance(registration.getConverter());
		}
		
		return null;
	}
	
	public static ApiServiceRegistrator instance() {
		if (instance == null) {
			instance = new ApiServiceRegistrator();
		}
		
		return instance;
	}
	
	private ServiceRegistration createService(Class<? extends IConfiguration> configuration,
			Class<? extends IAgent> executor, Class<? extends IConfigurationConverter<?>> converter) {
		
		return new ServiceRegistration()
			.withConfiguration(configuration)
			.withAgent(executor)
			.withConverter(converter);
	}
}
@@ -65,23 +65,74 @@
 va.util.
-HashMap
+ArrayList;%0Aimport java.util.HashMap;%0Aimport java.util.List
 ;%0Aimport
@@ -2895,24 +2895,123 @@
  null;%0A%09%7D%0A%09%0A
+%09public List%3CString%3E registeredIds() %7B%0A%09%09return new ArrayList%3C%3E(this.registrations.keySet());%0A%09%7D%0A%09%0A
 %09public stat

Add method to list registered service ids.