from __future__ import annotations

import inspect
from typing import Any, Callable

from .errors import ContractViolation


def positional_param_count(fn: Callable[..., Any]) -> tuple[int, bool]:
    sig = inspect.signature(fn)
    count = 0
    has_var_positional = False
    for p in sig.parameters.values():
        if p.kind in (inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD):
            count += 1
        elif p.kind == inspect.Parameter.VAR_POSITIONAL:
            has_var_positional = True
    return count, has_var_positional


def validate_min_positional_args(
    label: str,
    fn: Callable[..., Any],
    *,
    min_args: int,
    expected_shape: str,
) -> None:
    sig = inspect.signature(fn)
    count, has_var_positional = positional_param_count(fn)
    if count < min_args and not has_var_positional:
        raise ContractViolation(f"{label} must accept at least {min_args} args ({expected_shape}). Got: {sig}")
