package click.kamil.springstatemachineexporter.analysis.flow.eventid;

import java.util.List;

/**
 * Shared result for unique-or-hint-gated enum expand.
 * Members are concrete only (never {@code ENUM_SET:}/{@code SYMBOLIC} tokens).
 * <p>
 * <b>Publish contract:</b> do <em>not</em> publish {@link Source#UNIQUE} into polymorphic
 * events from this consult — use {@code recoverFromPath} / {@code resolveUnique} instead.
 * Poly widen only when {@link #adoptableAsPolyExpand()} is true (hint-licensed expand).
 * Do not treat non-empty {@link #members()} as expand without that check.
 */
public final class ExpandConsult {

    public enum Source {
        UNIQUE,
        ENUM_EXPAND,
        EMPTY
    }

    private final List<String> members;
    private final Source source;
    private final boolean licensedByHint;
    private final String enumType;

    private ExpandConsult(List<String> members, Source source, boolean licensedByHint, String enumType) {
        this.members = members == null ? List.of() : List.copyOf(members);
        this.source = source == null ? Source.EMPTY : source;
        this.licensedByHint = licensedByHint;
        this.enumType = enumType;
    }

    public static ExpandConsult empty() {
        return new ExpandConsult(List.of(), Source.EMPTY, false, null);
    }

    public static ExpandConsult unique(List<String> members, String enumType) {
        if (members == null || members.size() != 1) {
            return empty();
        }
        return new ExpandConsult(members, Source.UNIQUE, false, enumType);
    }

    public static ExpandConsult enumExpand(List<String> members, String enumType) {
        if (members == null || members.isEmpty()) {
            return empty();
        }
        return new ExpandConsult(members, Source.ENUM_EXPAND, true, enumType);
    }

    public List<String> members() {
        return members;
    }

    public Source source() {
        return source;
    }

    public boolean licensedByHint() {
        return licensedByHint;
    }

    public String enumType() {
        return enumType;
    }

    public boolean isEmpty() {
        return source == Source.EMPTY || members.isEmpty();
    }

    /** Hint-licensed multi-member widen suitable for polymorphicEvents. */
    public boolean adoptableAsPolyExpand() {
        return source == Source.ENUM_EXPAND && !members.isEmpty();
    }

    /** Single proven constant — publish via unique/recover, not poly expand. */
    public boolean isUniqueProof() {
        return source == Source.UNIQUE && members.size() == 1;
    }
}
