"""Pure role-model default scope replacement."""
from __future__ import annotations

from dataclasses import dataclass
from typing import Mapping


class ModelDefaultError(ValueError):
    """Raised when the selected default scope cannot supply candidates."""


@dataclass(frozen=True)
class ModelDefaultScopes:
    project: Mapping[str, tuple[str, ...]]
    global_: Mapping[str, tuple[str, ...]]
    bundled: Mapping[str, tuple[str, ...]]


def default_candidates(role: str, scopes: ModelDefaultScopes) -> tuple[str, ...]:
    """Return the first scope containing ``role`` without merging arrays."""
    for scope_name, values in (
        ("project", scopes.project),
        ("global", scopes.global_),
        ("bundled", scopes.bundled),
    ):
        if role not in values:
            continue
        candidates = tuple(values[role])
        if not candidates:
            raise ModelDefaultError(
                f"{scope_name} model defaults for {role!r} are empty"
            )
        return candidates
    return ()


def default_scope(role: str, scopes: ModelDefaultScopes) -> str | None:
    """Name the selected scope for resolver validation and diagnostics."""
    for scope_name, values in (
        ("project", scopes.project),
        ("global", scopes.global_),
        ("bundled", scopes.bundled),
    ):
        if role in values:
            return scope_name
    return None
