package org.implab.gradle.variants.artifacts;

import org.gradle.api.Action;
import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.NamedDomainObjectProvider;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.provider.Property;
import org.implab.gradle.variants.core.Variant;

/**
 * Plugin model object for one variant-level outgoing contract.
 *
 * <p>An outgoing variant connects a core {@link Variant} identity with the lazy
 * Gradle consumable configuration registered for that variant. It also exposes a
 * live container of slot identities. Slot identities are only declarations and do
 * not imply that a Gradle outgoing artifact variant or an {@link ArtifactAssembly}
 * has been materialized.
 */
public interface OutgoingVariant {
    /**
     * Returns the variant that owns this outgoing contract.
     *
     * @return variant identity
     */
    Variant getVariant();

    /**
     * Returns the provider of the registered consumable outgoing configuration.
     *
     * @return outgoing configuration provider
     */
    NamedDomainObjectProvider<? extends Configuration> getConfiguration();

    /**
     * Configures the registered outgoing configuration.
     *
     * @param action configuration action
     */
    default void configureOutgoing(Action<? super Configuration> action) {
        getConfiguration().configure(action);
    }

    /**
     * Returns the live slot identity container.
     *
     * <p>This collection is intended for discovery and selection. Slot presence does
     * not guarantee that the slot has a configured assembly body or a materialized
     * Gradle outgoing artifact variant.
     *
     * @see {@link ArtifactSlot}
     */
    NamedDomainObjectContainer<Slot> getSlots();

    /**
     * Returns the primary slot property.
     *
     * <p>If exactly one slot is declared, the single-slot convention uses that slot as
     * the primary one. Reading this property finalizes the selected primary slot.
     *
     * @return primary slot property
     */
    Property<Slot> getPrimarySlot();
}
