"""Shared fixtures for the execution tests.

Production code reads SPEC §6.8 verbatim (``sh -c`` on Unix, ``pwsh
-NoProfile -Command`` on Windows). The :func:`exec_shell` fixture
picks whichever shell the test host actually has and monkeypatches
``attractor.execution.local._resolve_shell`` for the test only.
Production logic never reads an env var to choose the shell — the
seam exists in tests, never in shipped behaviour.
"""

from __future__ import annotations

import shutil
from collections.abc import Iterator, Sequence

import pytest

from attractor.execution import local


def _pick_test_shell() -> tuple[str, Sequence[str]] | None:
    """Return ``(executable, leading_args)`` for the test shell, or
    ``None`` if no usable shell is on the host.

    We prefer the production shell pair for the host platform; if
    that's missing (e.g. Windows-without-pwsh) we fall back to
    ``sh`` (Git Bash on Windows ships with sh)."""
    pwsh = shutil.which("pwsh")
    if pwsh is not None:
        return (pwsh, ("-NoProfile", "-Command"))
    sh = shutil.which("sh")
    if sh is not None:
        return (sh, ("-c",))
    return None


@pytest.fixture
def exec_shell(monkeypatch: pytest.MonkeyPatch) -> Iterator[tuple[str, Sequence[str]]]:
    """Patch :func:`attractor.execution.local._resolve_shell` to the
    first shell we can find. Skip the test if neither ``pwsh`` nor
    ``sh`` is on PATH."""
    picked = _pick_test_shell()
    if picked is None:
        pytest.skip("no usable shell on PATH (need pwsh or sh)")

    def _patched() -> tuple[str, Sequence[str]]:
        return picked

    monkeypatch.setattr(local, "_resolve_shell", _patched)
    yield picked


@pytest.fixture
def is_pwsh(exec_shell: tuple[str, Sequence[str]]) -> bool:
    """True iff the active test shell is PowerShell."""
    return "pwsh" in exec_shell[0].lower() or "powershell" in exec_shell[0].lower()
