package org.implab.gradle.variants.artifacts;

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

/**
 * DSL model describing how a slot artifact is assembled.
 *
 * <p>Selection rules declared here may refer to internal build topology such as roles, layers or units.
 * Those selectors influence slot assembly only and do not become part of published artifact identity.
 *
 * <p>Regardless of the number of declared inputs, a slot is expected to materialize to a single published
 * artifact.
 */
public interface ArtifactAssemblySpec {
    /**
     * Contributes direct input material to the slot assembly.
     *
     * <p>The resulting slot still represents one published artifact.
     *
     * @param artifact direct input notation understood by the implementation
     */
    void from(Object artifact);

    /**
     * Selects outputs from the whole variant scope.
     *
     * @param action output selection rule
     */
    void fromVariant(Action<? super OutputSelectionSpec> action);

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

    /**
     * Selects outputs from a role inside the current variant.
     *
     * @param roleName role name used only for assembly-time selection
     * @param action output selection rule
     */
    void fromRole(String roleName, Action<? super OutputSelectionSpec> action);

    default void fromRole(String roleName, Closure<?> closure) {
        fromRole(roleName, Closures.action(closure));
    }

    /**
     * Selects outputs from a layer inside the current variant.
     *
     * @param layerName layer name used only for assembly-time selection
     * @param action output selection rule
     */
    void fromLayer(String layerName, Action<? super OutputSelectionSpec> action);

    default void fromLayer(String layerName, Closure<?> closure) {
        fromLayer(layerName, Closures.action(closure));
    }
}
