package cz.senslog.analytics.module.api;

import cz.senslog.analytics.domain.CollectorType;
import cz.senslog.analytics.module.*;
import cz.senslog.analytics.repository.*;
import io.vertx.sqlclient.Pool;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public final class Module {

    private static final Map<Class<? extends SimpleModule>, SimpleModule> MODULES = new ConcurrentHashMap<>();

    private static final Map<CollectorType, CollectorModule> COLLECTORS  = new ConcurrentHashMap<>();

    public static SimpleModule[] createModules(Pool sensLogDB) {
        AnalyticsRepository repo = new AnalyticsRepositoryImpl(sensLogDB);

        createModule(new ObservationReceiverModule(repo));
        createModule(new DoubleStatisticsModule(repo));
        createModule(new MoldAnalysisModule(repo));

        createModule(new AlertModule());
//        createModule(new ScheduleDBLoaderModule(repo));

        return MODULES.values().toArray(new SimpleModule[0]);
    }

    private static void createModule(SimpleModule module) {
        if (module instanceof CollectorModule c) {
            if (!COLLECTORS.containsKey(c.type())) {
                COLLECTORS.put(c.type(), c);
            }
        }
        if (!MODULES.containsKey(module.getClass())) {
            MODULES.put(module.getClass(), module);
        }
    }

    public static SimpleModule of(Class<? extends SimpleModule> aClass) {
        if (aClass == null) { return null; }
        return MODULES.get(aClass);
    }

    public static ModuleDescriptor collectorOf(CollectorType type) {
        if (type == null) { return null; }
        return COLLECTORS.get(type);
    }

    public static boolean containsCollectorOf(CollectorType type) {
        if (type == null) { return false; }
        return COLLECTORS.containsKey(type);
    }

    public static Collection<CollectorModule> collectors() {
        // TODO remake to ModuleDescriptor
        return COLLECTORS.values();
    }
}