from __future__ import annotations

from enum import Flag, auto

from ember.models.providers.utils import ResponsesRequest


class Feature(Flag):
    """Bitset of responses features requested by the caller."""

    NONE = 0
    TOOLS = auto()
    TOOL_CHOICE = auto()
    RESPONSE_FORMAT = auto()
    REASONING = auto()


class Cap(Flag):
    """Bitset of capabilities advertised by a model."""

    NONE = 0
    TOOLS = auto()
    JSON = auto()
    STRUCTURED_OUTPUT = auto()
    REASONING = auto()


# Map each requested feature to the acceptable capability flags. When multiple flags
# are present in the tuple they are treated as an OR condition.
REQUIREMENTS: dict[Feature, Cap] = {
    Feature.TOOLS: Cap.TOOLS,
    Feature.TOOL_CHOICE: Cap.TOOLS,
    Feature.RESPONSE_FORMAT: Cap.JSON | Cap.STRUCTURED_OUTPUT,
    Feature.REASONING: Cap.REASONING,
}


def required_features(request: ResponsesRequest) -> Feature:
    """Derive the feature bitset for a Responses request."""

    features = Feature.NONE
    if request.tools:
        features |= Feature.TOOLS
    if request.tool_choice is not None:
        features |= Feature.TOOL_CHOICE
    if request.response_format is not None:
        features |= Feature.RESPONSE_FORMAT
    if request.reasoning is not None:
        features |= Feature.REASONING
    return features


def feature_names(features: Feature) -> list[str]:
    """Return human-readable feature labels for diagnostics."""

    labels: list[str] = []
    for feature in Feature:
        if feature == Feature.NONE:
            continue
        if features & feature:
            assert feature.name is not None  # Enum members always have names
            labels.append(feature.name.lower())
    return labels
