import hashlib
import subprocess
from dataclasses import dataclass, field


@dataclass(frozen=True)
class Capability:
    executable: str
    version: str
    help_hash: str
    features: dict[str, bool]
    compatible: bool
    missing_features: list[str]
    #: Detected but non-essential capabilities, e.g. session resume.
    optional_features: dict[str, bool] = field(default_factory=dict)


def probe_binary(
    base_argv: list[str],
    probes: list[list[str]],
    tokens: dict[str, str],
    required: set[str] | None = None,
) -> Capability:
    """Run only version and help commands, then report which flags the build supports.

    `required` names the features whose absence makes the adapter unusable; every other
    entry in `tokens` is optional and is reported without failing the probe.
    """
    outputs: list[str] = []
    try:
        for args in probes:
            result = subprocess.run([*base_argv, *args], capture_output=True, text=True, timeout=10)
            outputs.append((result.stdout or "") + (result.stderr or ""))
    except (OSError, subprocess.TimeoutExpired) as error:
        outputs = [f"ERROR: {error}"]
    combined = "\n".join(outputs)
    names = required if required is not None else set(tokens)
    features = {name: token in combined for name, token in tokens.items()}
    missing = sorted(name for name in names if not features.get(name))
    return Capability(
        executable=base_argv[0],
        version=outputs[0].strip(),
        help_hash=hashlib.sha256(combined.encode()).hexdigest(),
        features=features,
        compatible=not missing,
        missing_features=missing,
        optional_features={name: value for name, value in features.items() if name not in names},
    )
