package org.implab.gradle.variants.derived;

import java.util.Optional;
import java.util.Set;

import org.implab.gradle.variants.core.Layer;
import org.implab.gradle.variants.core.Role;
import org.implab.gradle.variants.core.Variant;

public interface RoleProjectionsView {
    Set<RoleProjection> getProjections();

    Set<RoleProjection> getProjectionsForVariant(Variant variant);

    Set<RoleProjection> getProjectionsForRole(Role role);

    Optional<RoleProjection> findProjection(Variant variant, Role role);

    default RoleProjection getProjection(Variant variant, Role role) {
        return findProjection(variant, role)
                .orElseThrow(() -> new IllegalArgumentException(
                        "Role projection for variant '" + variant.getName()
                                + "' and role '" + role.getName() + "' not found"));
    }

    boolean contains(Variant variant, Role role);

    Set<CompileUnit> getUnits(RoleProjection projection);

    default Set<Layer> getLayers(RoleProjection projection) {
        return getUnits(projection).stream()
                .map(CompileUnit::layer)
                .collect(java.util.stream.Collectors.toUnmodifiableSet());
    }
}