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

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

import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.model.ObjectFactory;
import org.implab.gradle.common.core.lang.Deferred;
import org.implab.gradle.common.sources.GenericSourceSet;

public class SourceSetRegistry {
    private final Map<String, Deferred<GenericSourceSet>> materialized = new HashMap<>();
    private final NamedDomainObjectContainer<GenericSourceSet> sourceSets;
    private final ObjectFactory objectFactory;

    public SourceSetRegistry(ObjectFactory objectFactory) {
        this.objectFactory = objectFactory;
        this.sourceSets = objectFactory.domainObjectContainer(GenericSourceSet.class, this::createSourceSet);
    }

    void forEachMaterialized(Consumer<? super GenericSourceSet> consumer) {
        materialized.values().stream()
            .filter(Deferred::resolved)
            .map(Deferred::value)
            .forEach(consumer);
    }

    public NamedDomainObjectContainer<GenericSourceSet> sourceSets() {
        return sourceSets;
    }

    public void whenMaterialized(String name, Consumer<? super GenericSourceSet> consumer) {
        materialized(name).whenResolved(consumer);
    }

    private GenericSourceSet createSourceSet(String name) {
        var sourceSet = objectFactory.newInstance(GenericSourceSet.class, name);
        materialized(name).resolve(sourceSet);
        return sourceSet;
    }

    private Deferred<GenericSourceSet> materialized(String name) {
        return materialized.computeIfAbsent(name, k -> new Deferred<>());
    }
}
