package org.gcube.application.geoportal.service;

import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.caches.Engine;
import org.gcube.application.cms.implementations.ImplementationProvider;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.geoportal.common.rest.InterfaceConstants;
import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.gcube.application.geoportal.service.engine.mongo.UCDManagerI;
import org.gcube.application.geoportal.service.engine.providers.ConfigurationCache;
import org.gcube.application.geoportal.service.engine.providers.MongoClientProvider;
import org.gcube.application.geoportal.service.engine.providers.PluginManager;
import org.gcube.application.geoportal.service.engine.providers.StorageClientProvider;
import org.gcube.application.geoportal.service.engine.providers.ucd.ProfileMap;
import org.gcube.application.geoportal.service.engine.providers.ucd.SingleISResourceUCDProvider;
import org.gcube.application.geoportal.service.engine.providers.ucd.UCDManager;
import org.gcube.application.geoportal.service.model.internal.db.Mongo;
import org.gcube.application.geoportal.service.rest.DocsGenerator;
import org.gcube.application.geoportal.service.rest.Plugins;
import org.gcube.application.geoportal.service.rest.ProfiledDocuments;
import org.gcube.application.geoportal.service.rest.UseCaseDescriptors;
import org.glassfish.jersey.server.ResourceConfig;

import javax.ws.rs.ApplicationPath;
import java.util.Collections;
import java.util.Map;

@ApplicationPath(InterfaceConstants.APPLICATION_PATH)
@Slf4j
public class GeoPortalService extends ResourceConfig{

	public <T> Map<Engine<T>,Class<T>> customImplementations(){
		return Collections.EMPTY_MAP;
	}
	
	public GeoPortalService() {
		super();
		//Register interrfaces

		log.info("Initializing serialization");
		JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
		provider.setMapper(Serialization.mapper);
		register(provider);


		registerClasses(ProfiledDocuments.class);
		registerClasses(UseCaseDescriptors.class);
		registerClasses(Plugins.class);
		registerClasses(DocsGenerator.class);

		log.info("Setting implementations .. ");

		ImplementationProvider.get().setEngine(new MongoClientProvider(), Mongo.class);
		ImplementationProvider.get().setEngine(new StorageClientProvider(), StorageUtils.class);
		ImplementationProvider.get().setEngine(new SingleISResourceUCDProvider(), ProfileMap.class);
		ImplementationProvider.get().setEngine(new PluginManager(), PluginManager.PluginMap.class);
		ImplementationProvider.get().setEngine(new UCDManager(),UCDManagerI.class);
		ImplementationProvider.get().setEngine(new ConfigurationCache(), ConfigurationCache.ConfigurationMap.class);


		for(Map.Entry<Engine<Object>, Class<Object>> entry : customImplementations().entrySet()){
			log.warn("LOADING CUSTOM ENGINE : {} serving {}",entry.getKey(),entry.getValue());
			ImplementationProvider.get().setEngine(entry.getKey(), entry.getValue());
		}

		log.debug("ENGINES ARE : ");
		ImplementationProvider.get().getManagerList().forEach(
				(aClass, s) -> log.debug("{} serving {} ",aClass,s));

		ImplementationProvider.get().initEngines();


	}



	
}
