import subprocess
from types import SimpleNamespace


def test_browse_sh_availability_reports_missing_cli(monkeypatch):
    from services import browse_sh_tool
    from services.browse_sh_tool import BrowseShTool

    monkeypatch.delenv("BROWSE_SH_CLI", raising=False)
    monkeypatch.setattr(browse_sh_tool.shutil, "which", lambda _name: None)

    availability = BrowseShTool().availability()

    assert availability.available is False
    assert availability.command == tuple()
    assert "未安裝" in availability.reason


def test_browse_sh_build_command_prefers_env_override(monkeypatch):
    from services import browse_sh_tool
    from services.browse_sh_tool import BrowseShTool

    monkeypatch.setenv("BROWSE_SH_CLI", "/opt/bin/browse")
    monkeypatch.setattr(browse_sh_tool.shutil, "which", lambda _name: "/usr/local/bin/browse")

    assert BrowseShTool().build_command(("skills", "list")) == (
        "/opt/bin/browse",
        "skills",
        "list",
    )


def test_browse_sh_run_returns_success(monkeypatch):
    from services.browse_sh_tool import BrowseShTool

    calls = []

    def fake_run(command, **kwargs):
        calls.append((command, kwargs))
        return SimpleNamespace(returncode=0, stdout="ok", stderr="")

    monkeypatch.setattr("services.browse_sh_tool.subprocess.run", fake_run)

    result = BrowseShTool(cli_path="/bin/browse").run(("skills", "list"), require_available=False)

    assert result.ok is True
    assert result.command == ("/bin/browse", "skills", "list")
    assert result.stdout == "ok"
    assert calls[0][0] == ("/bin/browse", "skills", "list")


def test_browse_sh_run_converts_timeout(monkeypatch):
    from services.browse_sh_tool import BrowseShTool

    def fake_run(command, **_kwargs):
        raise subprocess.TimeoutExpired(command, timeout=1, output="partial", stderr="late")

    monkeypatch.setattr("services.browse_sh_tool.subprocess.run", fake_run)

    result = BrowseShTool(cli_path="/bin/browse").run(("screenshot",), require_available=False)

    assert result.ok is False
    assert result.timed_out is True
    assert result.stdout == "partial"
    assert result.stderr == "late"


def test_browse_sh_run_surfaces_broken_cli(monkeypatch):
    from services.browse_sh_tool import BrowseShTool

    def fake_run(command, **kwargs):
        if command[-1] == "--version":
            return SimpleNamespace(returncode=1, stdout="", stderr="node dyld missing icu4c")
        return SimpleNamespace(returncode=0, stdout="", stderr="")

    monkeypatch.setattr("services.browse_sh_tool.subprocess.run", fake_run)

    result = BrowseShTool(cli_path="/bin/browse").run(("skills", "list"))

    assert result.ok is False
    assert "icu4c" in result.unavailable_reason
