package org.implab.gradle.variants.artifacts.internal;

import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;

import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ProviderFactory;
import org.implab.gradle.variants.artifacts.OutgoingVariant;
import org.implab.gradle.variants.core.Variant;

public class OutgoingRegistry {
    private final Map<Variant, DefaultOutgoingConfiguration> outgoingByVariant = new LinkedHashMap<>();
    private final List<Consumer<? super DefaultOutgoingConfiguration>> hooks = new LinkedList<>();

    private final ConfigurationContainer configurations;
    private final ObjectFactory objects;
    private final ProviderFactory providers;

    public OutgoingRegistry(ConfigurationContainer configurations, ObjectFactory objects, ProviderFactory providers) {
        this.configurations = configurations;
        this.objects = objects;
        this.providers = providers;
    }

    public Optional<OutgoingVariant> findOutgoing(Variant variant) {
        return Optional.ofNullable(outgoingByVariant.get(variant));
    }

    public OutgoingVariant maybeCreate(Variant variant) {
        var outgoing = outgoingByVariant.computeIfAbsent(variant, this::newOutgoingConfiguration);
        hooks.forEach(hook -> hook.accept(outgoing));
        return outgoing;
    }

    public void all(Consumer<? super OutgoingVariant> action) {
        outgoingByVariant.values().forEach(action);
        hooks.add(action);
    }

    private DefaultOutgoingConfiguration newOutgoingConfiguration(Variant variant) {
        var configuration = configurations.register(outgoingConfigurationName(variant));

        return new DefaultOutgoingConfiguration(variant, configuration, objects, providers);
    }

    private String outgoingConfigurationName(Variant variant) {
        return variant.getName() + "Elements";
    }


}
