package eu.dnetlib.wds.resolver;


import com.mongodb.MongoClient;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.IMongodConfig;
import de.flapdoodle.embed.mongo.config.MongoCmdOptionsBuilder;
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;
import eu.dnetlib.pid.resolver.mdstore.plugin.ResolverSerializer;
import eu.dnetlib.pid.resolver.store.ResolverStore;
import eu.dnetlib.springutils.stringtemplate.StringTemplateFactory;
import eu.dnetlib.wds.resolver.serializers.WDSResolverSerializer;
import net.sf.ehcache.Cache;
import org.antlr.stringtemplate.StringTemplate;
import org.springframework.cache.ehcache.EhCacheFactoryBean;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;

@Configuration
public class ResolverConfiguration {

    @Bean
    public MongoClient mongoClient() throws IOException {
        MongodStarter starter = MongodStarter.getDefaultInstance();
        String bindIp = "localhost";
        int port = 12345;
        IMongodConfig mongodConfig = new MongodConfigBuilder()
                .version(Version.Main.PRODUCTION)
                .net(new Net(bindIp, port, Network.localhostIsIPv6()))
                .cmdOptions(new MongoCmdOptionsBuilder()
                        .useNoJournal(false)
                        .build())
                .build();
        MongodExecutable mongodExecutable = starter.prepare(mongodConfig);
        mongodExecutable.start();

        return new MongoClient(bindIp, port);
    }


    @Bean
    public ResolverStore storeManager() throws IOException {
        ResolverStore rs = new ResolverStore();
        rs.setCollectionName("resolvedCollection");
        rs.setDatabaseName("resolvedDB");
        rs.setMongoClient(mongoClient());
        return rs;
    }

    @Bean
    public EhCacheManagerFactoryBean cacheFactory() {
        EhCacheManagerFactoryBean cacheFactory = new EhCacheManagerFactoryBean();
        cacheFactory.setCacheManagerName("testCacheFactory");
        return cacheFactory;
    }

    @Bean
    public EhCacheFactoryBean ResolverCache() {
        EhCacheFactoryBean doiCacheFactoryBean = new EhCacheFactoryBean();
        doiCacheFactoryBean.setEternal(false);
        doiCacheFactoryBean.setTimeToLive(0);
        doiCacheFactoryBean.setTimeToIdle(36000);
        doiCacheFactoryBean.setMaxEntriesLocalHeap(10000);
        doiCacheFactoryBean.setMaxEntriesLocalDisk(20000);
        doiCacheFactoryBean.setCacheManager(cacheFactory().getObject());
        doiCacheFactoryBean.setCacheName("TestResolverCache");
        return doiCacheFactoryBean;
    }


    @Bean
    public OpenAireResolver openAireResolver() {
        final OpenAireResolver res = (OpenAireResolver) new OpenAireResolver().setOrder(0);
        res.setCache((Cache) ResolverCache().getObject());
        res.setName("openAireResolver");
        return res;
    }

    @Bean
    public DLIResolver dliResolver() {
        final DLIResolver res = (DLIResolver) new DLIResolver().setOrder(0);
        res.setCache((Cache) ResolverCache().getObject());
        res.setName("dliResolver");
        return res;
    }

    @Bean
    public WDSResolvedObjectFactory resolvedObjectFactory() {
        return new WDSResolvedObjectFactory();
    }



    @Bean
    public ResolverSerializer resolverSerializer() throws Exception {
        WDSResolverSerializer serializer = new WDSResolverSerializer();

        serializer.setDmfTemplate(dmfTemplate());
        serializer.setPmfTemplate(pmfTemplate());

        return serializer;
    }

    @Bean
    public StringTemplate dmfTemplate() throws Exception {
        final StringTemplateFactory s= new StringTemplateFactory();
        s.setTemplate(new ClassPathResource("/eu/dnetlib/wds/templates/DMFXML.st"));
        return s.getObject();
    }

    @Bean
    public StringTemplate pmfTemplate() throws Exception {
        final StringTemplateFactory s= new StringTemplateFactory();
        s.setTemplate(new ClassPathResource("/eu/dnetlib/wds/templates/PMFXML.st"));
        return s.getObject();
    }

}
