"""Script dispatch must use SSH readiness, not Agent is_online heartbeat."""

from unittest.mock import AsyncMock, MagicMock, patch

import pytest

from server.application.services.script_service import ScriptService
from server.domain.models import Server


def _make_service() -> ScriptService:
    return ScriptService(
        script_repo=MagicMock(),
        execution_repo=MagicMock(),
        credential_repo=MagicMock(),
        server_repo=MagicMock(),
        audit_repo=MagicMock(),
    )


@pytest.mark.asyncio
async def test_dispatch_ssh_when_agent_offline():
    """Servers without Agent heartbeat should still receive SSH script exec."""
    service = _make_service()
    server = Server(
        id=7,
        name="srv-7",
        domain="10.0.0.7",
        port=22,
        username="root",
        auth_method="password",
        password="enc",
        is_online=False,
        connectivity="ok",
    )
    service.server_repo.get_by_id = AsyncMock(return_value=server)

    mock_exec = AsyncMock(
        return_value={"status": "ok", "stdout": "ok\n", "stderr": "", "exit_code": 0},
    )
    with patch.object(service, "_call_ssh_exec", mock_exec):
        results = await service._dispatch_to_servers([7], "echo ok", timeout=30)

    assert results["7"]["exit_code"] == 0
    mock_exec.assert_awaited_once()


@pytest.mark.asyncio
async def test_dispatch_skips_missing_ssh_credentials():
    service = _make_service()
    server = Server(
        id=8,
        name="srv-8",
        domain="10.0.0.8",
        port=22,
        username="root",
        auth_method="key",
        is_online=True,
    )
    service.server_repo.get_by_id = AsyncMock(return_value=server)

    results = await service._dispatch_to_servers([8], "echo ok", timeout=30)

    assert results["8"]["exit_code"] == -1
    assert "SSH" in results["8"]["stderr"]
