package org.royjacobs.lazybot.store;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Throwables;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.extern.slf4j.Slf4j;
import net.openhft.chronicle.map.ChronicleMap;
import org.royjacobs.lazybot.api.store.Store;
import org.royjacobs.lazybot.config.DatabaseConfig;

import javax.inject.Inject;
import java.io.File;
import java.io.IOException;

@Slf4j
public class PersistentStoreFactory implements StoreFactory {
    private final ObjectMapper objectMapper;
    private final DatabaseConfig databaseConfig;
    private final Cache<String, Object> storeCache;

    @Inject
    public PersistentStoreFactory(final ObjectMapper objectMapper, final DatabaseConfig databaseConfig) {
        this.objectMapper = objectMapper;
        this.databaseConfig = databaseConfig;
        storeCache = CacheBuilder.newBuilder().maximumSize(10000).build();
    }

    public <T> Store<T> get(final String key, final Class<T> clazz) {
        final Object existingStore = storeCache.getIfPresent(key);
        if (existingStore != null) return (JacksonStore<T>)existingStore;

        final File file = new File(databaseConfig.getFolder(), key + ".db");
        final ChronicleMap<String, String> map;
        try {
            map = ChronicleMap.of(String.class, String.class).averageKeySize(32).averageValueSize(100).entries(100).createOrRecoverPersistedTo(file);
        } catch (IOException e) {
            log.error("Could not create or open persistent map: " + file.toString(), e);
            throw Throwables.propagate(e);
        }

        final Store<T> store = new JacksonStore<>(objectMapper, map, clazz);
        storeCache.put(key, store);
        return store;
    }
}

@@ -464,16 +464,121 @@
 ception;
+%0Aimport java.nio.file.FileAlreadyExistsException;%0Aimport java.nio.file.Files;%0Aimport java.nio.file.Paths;
 %0A%0A@Slf4j
@@ -1283,24 +1283,340 @@
 tingStore;%0A%0A
+        try %7B%0A            Files.createDirectory(Paths.get(databaseConfig.getFolder()));%0A        %7D catch (FileAlreadyExistsException e)%7B%0A            // fine!%0A        %7D catch (IOException e) %7B%0A            log.error(%22Could not create storage folder for database%22);%0A            throw Throwables.propagate(e);%0A        %7D%0A%0A
         fina

Create database storage folder if it doesn't yet exist