package org.gcube.application.cms.sdi.plugins;

import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.caches.AbstractScopedMap;
import org.gcube.application.cms.implementations.ISInterface;
import org.gcube.application.cms.implementations.ImplementationProvider;
import org.gcube.application.cms.plugins.InitializablePlugin;
import org.gcube.application.cms.plugins.faults.InitializationException;
import org.gcube.application.cms.plugins.faults.ShutDownException;
import org.gcube.application.cms.plugins.implementations.AbstractPlugin;
import org.gcube.application.cms.plugins.reports.InitializationReport;
import org.gcube.application.cms.plugins.reports.Report;
import org.gcube.application.cms.sdi.engine.PostgisIndexer;
import org.gcube.application.cms.sdi.engine.SDIManagerWrapper;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.rest.DatabaseConnection;

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

@Slf4j
public abstract class SDIAbstractPlugin extends AbstractPlugin implements InitializablePlugin {

    protected static AbstractScopedMap<SDIManagerWrapper> sdiCache;

    protected static AbstractScopedMap<DatabaseConnection> postgisCache;

    @Synchronized
    private static void initCache(){
        if(sdiCache==null) {
            log.info("Creating internal caches.. ");
            sdiCache = new AbstractScopedMap<SDIManagerWrapper>("SDI-CACHE") {
                @Override
                protected SDIManagerWrapper retrieveObject(String context) throws ConfigurationException {
                    try {
                        return new SDIManagerWrapper();
                    } catch (Exception e) {
                        throw new ConfigurationException(e);
                    }
                }
            };
            sdiCache.setTTL(Duration.of(10, ChronoUnit.MINUTES));
        }
        if(postgisCache==null) {
            postgisCache = new AbstractScopedMap<DatabaseConnection>("POSTGIS-CREDENTIALS") {
                @Override
                protected DatabaseConnection retrieveObject(String context) throws ConfigurationException {
                    try {
                        DatabaseConnection db =  ImplementationProvider.get().getProvidedObjectByClass(ISInterface.class).
                                queryForDatabase("Database","postgis", "GNA_DB","Concessioni");
                        log.debug("Postgis Connection in {} is {} ", context,db);
                        return db;
                    } catch (Exception e) {
                        throw new ConfigurationException(e);
                    }
                }
            };
            postgisCache.setTTL(Duration.of(10, ChronoUnit.MINUTES));
        }
    }


    @Override
    public InitializationReport init() throws InitializationException {
        InitializationReport report = new InitializationReport();
        try{
            initCache();
            PostgisIndexer.init();
            report.setStatus(Report.Status.OK);
        } catch (Throwable e) {
            throw new InitializationException("SDI Plugins : Unable to initialize Internal Caches ",e);
        }
        return report;
    }

    @Override
    public void shutdown() throws ShutDownException {

    }
}
