package org.gcube.application.geoportal.service.engine.providers;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.caches.AbstractScopedMap;
import org.gcube.application.cms.caches.TimedMap;
import org.gcube.application.geoportal.common.model.configuration.Configuration;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.service.engine.mongo.ProfiledMongoManager;

import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAmount;

@Slf4j
public class ConfigurationCache extends AbstractScopedMap<ConfigurationCache.ConfigurationMap> {

    public static class ConfigurationMap extends TimedMap<String, Configuration>{
        public ConfigurationMap(@NonNull String name) {
            super(name);
        }

        @Override
        public TemporalAmount getTTL(){
            return Duration.of(2, ChronoUnit.MINUTES);
        }

        @Override
        protected Configuration retrieveObject(String key) throws ConfigurationException {
            return getForProfile(key);
        }
    }


    public ConfigurationCache() {
        super("Configuration Cache");
    }

    @Override
    protected ConfigurationMap retrieveObject(String key) throws ConfigurationException {
        return new ConfigurationMap(key+"_configuration_cache") {
       };
    }


    private static Configuration getForProfile(String profileID) throws ConfigurationException{
       log.info("Evaluating Configuration for profile {} ",profileID);
        try{
            return new ProfiledMongoManager(profileID).getConfiguration();
        } catch (ConfigurationException e) {
            log.error("Unable to get configuration for {} ",profileID,e);
            throw e;
        } catch (Throwable t){
            log.error("Unable to get configuration for {} ",profileID,t);
            throw new ConfigurationException("Unable to get configuration for "+profileID,t);
        }

    }
}
