"""Runtime regression tests for local python-vagrant execution.

These tests cover the real `_vagrant_run()` local path instead of mocking the
helper away. They guard against the `fileno` failure caused by wiring StringIO
objects into python-vagrant's subprocess stderr/stdout handling.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import pytest

from mcp_vm_blackbox.targets import TargetConfig
from mcp_vm_blackbox.vagrant_tools import _vagrant_run

if TYPE_CHECKING:
    from pathlib import Path


class _FakeVagrant:
    """Minimal python-vagrant stand-in for local-path tests.

    Accepts the same keyword args that vagrant_tools._vagrant_run passes to
    vagrant.Vagrant (root, quiet_stdout, quiet_stderr, env) via **kwargs so
    this fake works regardless of which subset of args the source passes.
    The status() method returns a string that includes the expected output
    text so that the _vagrant_run local path can use it directly.
    """

    def __init__(self, **_: object) -> None:
        pass

    def status(self, vm_name: str | None = None) -> str:
        """Return a status string that includes the expected output text."""
        del vm_name
        return "Current machine states:\ndefault running\n"


class _FakeVagrantNoOutput:
    """Stand-in that returns a value but emits no stdout text."""

    def __init__(self, **_: object) -> None:
        pass

    def status(self, vm_name: str | None = None) -> str:
        del vm_name
        return "status-result"


@pytest.mark.asyncio
async def test_vagrant_run_local_status_uses_real_file_handles(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
    """Local status path should work without StringIO/fileno failures."""
    monkeypatch.setattr("mcp_vm_blackbox.vagrant_tools.vagrant.Vagrant", _FakeVagrant)

    stdout, stderr, exit_code, duration_s = await _vagrant_run(
        TargetConfig(ssh_host=""), ["status"], repo_root=str(tmp_path)
    )

    assert exit_code == 0
    assert "Current machine states:" in stdout
    assert stderr == ""
    assert duration_s >= 0


@pytest.mark.asyncio
async def test_vagrant_run_local_falls_back_to_dispatch_result_when_stdout_empty(
    monkeypatch: pytest.MonkeyPatch, tmp_path: Path
) -> None:
    """Commands returning values without stdout should still produce output."""
    monkeypatch.setattr("mcp_vm_blackbox.vagrant_tools.vagrant.Vagrant", _FakeVagrantNoOutput)

    stdout, stderr, exit_code, _duration_s = await _vagrant_run(
        TargetConfig(ssh_host=""), ["status"], repo_root=str(tmp_path)
    )

    assert exit_code == 0
    assert stdout == "status-result"
    assert stderr == ""
