package info.bukova.isspst;

import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.services.Service;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ModuleUtils {
	
	public static List<Module> getActiveModules() {
		List<Module> modules = new ArrayList<Module>();
		
		for (Module m : Arrays.asList(Constants.MODULES)) {
			if (m.isActive()) {
				modules.add(m);
			}
		}
		
		return modules;
	}
	
	public static Module getModule(Class<?> serviceClass) {
		for (Module m : Constants.MODULES) {
			if (Arrays.asList(serviceClass.getInterfaces()).contains(m.getServiceClass())) {
				return m;
			}
		}
		
		return null;
	}
	
	public static Module getModule(String id) {
		for (Module m : Constants.MODULES) {
			if (m.getId().equals(id)) {
				return m;
			}
		}
		
		return null;
	}

	public static Module getModule(DataModel entity, ServletContext sc) {
		WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
		for (Module m : Constants.MODULES) {
			Service<?> service;

			try {
				service = (Service<?>) ctx.getBean(m.getServiceClass());
			} catch (NoSuchBeanDefinitionException e) {
				String[] beans = ctx.getBeanNamesForType(m.getServiceClass());

				for (String s : beans) {
					service = (Service<?>) ctx.getBean(s);

					if (service.getEntityClasses().contains(entity.getClass())) {
						return m;
					}
				}

				continue;
			} catch (ClassCastException e) { //nestandardní moduly neřeší...
				continue;
			}

			if (service.getEntityClasses().contains(entity.getClass())) {
				return m;
			}
		}

		return null;
	}

	public static Service<?> getServiceInstance(Module m, ServletContext sc) {
		WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);

		try {
			return (Service<?>) ctx.getBean(m.getServiceClass());
		} catch (NoSuchBeanDefinitionException e) {
			String[] beans = ctx.getBeanNamesForType(m.getServiceClass());
			return (Service<?>) ctx.getBean(beans[0]);
		}
	}
	
	public static boolean isActive(String id) {
		return getModule(id).isActive();
	}

}
