package org.implab.gradle.variants.core;

import org.gradle.api.Action;
import org.gradle.api.NamedDomainObjectContainer;
import org.implab.gradle.common.core.lang.Closures;

import groovy.lang.Closure;

/**
 * Root extension:
 *
 * variants {
 * layers { ... }
 * roles { ... }
 *
 * variant("browser") {
 * role("production") {
 * layers("main", "generated", "mainRjs")
 * }
 * }
 * }
 *
 */
public interface VariantsExtension {

    /**
     * Domain of layers.
     */
    NamedDomainObjectContainer<Layer> getLayers();

    /**
     * Domain of roles.
     */
    NamedDomainObjectContainer<Role> getRoles();

    /**
     * Declared variants.
     */
    NamedDomainObjectContainer<VariantDefinition> getVariantDefinitions();

    /**
     * Creates or returns an existing variant and configures it.
     */
    default VariantDefinition variant(String name) {
        return getVariantDefinitions().maybeCreate(name);
    }

    /**
     * Creates or returns an existing variant and configures it.
     */
    default VariantDefinition variant(String name, Action<? super VariantDefinition> action) {
        var variant = variant(name);
        action.execute(variant);
        return variant;
    }

    default VariantDefinition variant(String name, Closure<?> closure) {
        return variant(name, Closures.action(closure));
    }

    /**
     * Registers an action to be executed when the extension is finalized.
     *
     * The specified action will receive the unmodifiable snapshot of the variants.
     *
     * @param action The callback to be executed when variants are finalized
     */
    void whenFinalized(Action<? super VariantsView> action);

    default void whenFinalized(Closure<?> action) {
        whenFinalized(Closures.action(action));
    }

}