"""Smoke tests for ``mgf.common.process``.

Minimal post-install sanity: if these pass, the package was installed
correctly + the public surface is reachable + the shortest happy
paths work. No fixtures, no bootstrap, no extras — pure stdlib +
``mgf-common`` core. Fast (< 1 s on a normal machine).

Run in isolation::

    pytest -m smoke

These are the tests a downstream CI job would run as a "did the
wheel install correctly?" pre-flight check before the heavier
integration suite.
"""

from __future__ import annotations

import pytest

pytestmark = pytest.mark.smoke


def test_top_level_imports() -> None:
    # Every name from PUBLIC_API.md `mgf.common.process` is importable.
    from mgf.common.process import (
        AllOf,
        AnyOf,
        CallableReady,
        HttpReady,
        LogLineReady,
        PortReady,
        ProcessResult,
        ReadinessProbe,
        Service,
        run,
    )

    # Light check that they're the expected types.
    assert callable(run)
    assert callable(Service)
    assert all(
        callable(p)
        for p in [
            PortReady,
            HttpReady,
            LogLineReady,
            CallableReady,
            AllOf,
            AnyOf,
        ]
    )
    assert ProcessResult is not None
    assert ReadinessProbe is not None


def test_exception_taxonomy_imports() -> None:
    from mgf.common.exceptions import (
        OperationError,
        ProcessError,
        ProcessNonZeroExitError,
        ProcessSignaledError,
        ProcessTimeoutError,
        ServiceNotReadyError,
    )

    # The MRO contract — every Process* error catches via
    # `except OperationError:` for EH-04 top-level handlers.
    for leaf in (
        ProcessTimeoutError,
        ProcessNonZeroExitError,
        ProcessSignaledError,
        ServiceNotReadyError,
    ):
        assert issubclass(leaf, ProcessError)
        assert issubclass(leaf, OperationError)


def test_run_echo_returns_zero() -> None:
    from mgf.common.process import run

    result = run(["echo", "smoke"])
    assert result.returncode == 0
    assert result.stdout == "smoke"
    assert len(result.command_id) == 8


def test_run_check_false_preserves_returncode() -> None:
    from mgf.common.process import run

    result = run(["false"], check=False)
    assert result.returncode == 1


def test_service_construction_does_not_launch() -> None:
    # Constructing a Service must not start the process — that's
    # the start() / context-manager job. Verifies no work-on-init.
    from mgf.common.process import PortReady, Service

    svc = Service(
        ["sleep", "1"],
        ready=PortReady("127.0.0.1", 1, connect_timeout_s=0.05),
    )
    assert not svc.is_running
    assert svc.pid is None
    assert svc.returncode is None
    # repr exists and includes the name (v0.23.0).
    rep = repr(svc)
    assert "sleep" in rep
    assert "not-started" in rep


def test_command_accepts_tuple() -> None:
    # v0.23.0 tuple acceptance.
    from mgf.common.process import run

    r = run(("echo", "tuple-input"))
    assert r.stdout == "tuple-input"
    assert r.command == ["echo", "tuple-input"]


def test_command_rejects_shell_string() -> None:
    # Command-injection-by-construction safety still holds.
    from mgf.common.process import run

    with pytest.raises(TypeError, match="not a str"):
        run("echo unsafe")  # type: ignore[arg-type]
