package org.adrianvictor.lib.versioning;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

public class DefaultVersionedServiceFactory implements VersionedServiceFactory {
    private final VersionMatcher versionMatcher;
    private final Map<Class<?>, Map<String, Supplier<?>>> serviceRegistrations = new HashMap<>();

    public DefaultVersionedServiceFactory(VersionMatcher versionMatcher) {
        this.versionMatcher = versionMatcher;
    }

    @Override
    public <T> void register(Class<T> serviceType, String versionSuffix, Supplier<T> supplier) {
        serviceRegistrations
                .computeIfAbsent(serviceType, k -> new HashMap<>())
                .put(versionSuffix, supplier);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T getService(Class<T> serviceType) {
        String serverVersion = versionMatcher.getServerVersion();
        String versionSuffix = versionMatcher.getClassSuffix(serverVersion);

        Map<String, Supplier<?>> versionSuppliers = serviceRegistrations.get(serviceType);
        if (versionSuppliers == null || !versionSuppliers.containsKey(versionSuffix)) {
            throw new IllegalStateException("No service registered for type " + serviceType.getName() + " and version " + versionSuffix + ". Current server version: " + serverVersion);
        }
        return (T) versionSuppliers.get(versionSuffix).get();
    }
}
