"""Tests for post-create server onboarding automation."""

from __future__ import annotations

from unittest.mock import AsyncMock, patch

import pytest

from server.utils.posix_paths import is_unset_target_path


@pytest.mark.parametrize(
    "target_path,expect_detect",
    [
        ("", True),
        ("/www/wwwroot", True),
        ("/www/wwwroot/site", False),
    ],
)
def test_onboard_skips_detect_when_path_set(target_path, expect_detect):
    assert is_unset_target_path(target_path) is expect_detect


@pytest.mark.asyncio
async def test_schedule_server_onboarding_delegates_to_batch():
    from server.application.services.server_onboarding_service import schedule_server_onboarding

    with patch(
        "server.application.services.server_batch_service.start_batch_job",
        new_callable=AsyncMock,
        return_value={"job_id": 99, "status": "running", "total": 1},
    ) as start:
        job = await schedule_server_onboarding([12], operator="admin")
    start.assert_awaited_once_with(op="onboard", server_ids=[12], operator="admin")
    assert job["job_id"] == 99


@pytest.mark.asyncio
async def test_run_onboard_non_root_success():
    from server.application.services.server_batch_service import _run_onboard
    from server.domain.models import Server
    from server.infrastructure.redis import server_batch_store as sbs

    server = Server(id=1, name="t", domain="1.2.3.4", username="ubuntu", target_path="")
    live = sbs.init_live(
        job_id=1,
        op="onboard",
        label="新服务器初始化",
        server_ids=[1],
        operator="admin",
    )

    async def invoke(_live, handler):
        item = await handler(1, {1: server}, {1: "t"}, _live)
        sbs.record_result(_live, item)

    with patch(
        "server.application.services.server_batch_service._run_with_semaphore",
        new_callable=AsyncMock,
        side_effect=invoke,
    ):
        with patch(
            "server.application.services.files_sudoers_service.install_nexus_files_sudoers",
            new_callable=AsyncMock,
            return_value={"ok": True, "action": "already_ok"},
        ):
            with patch(
                "server.application.server_batch_common.detect_and_save_target_path",
                new_callable=AsyncMock,
                return_value={"success": True, "stdout": "target_path → /www/wwwroot/shop"},
            ):
                await _run_onboard(live)

    assert live["results"]["1"]["success"] is True
    assert "sudo" in live["results"]["1"]["stdout"]


@pytest.mark.asyncio
async def test_run_onboard_detect_fail_still_success():
    from server.application.services.server_batch_service import _run_onboard
    from server.domain.models import Server
    from server.infrastructure.redis import server_batch_store as sbs

    server = Server(id=3, name="u", domain="3.4.5.6", username="ubuntu", target_path="")
    live = sbs.init_live(
        job_id=3,
        op="onboard",
        label="新服务器初始化",
        server_ids=[3],
        operator="admin",
    )

    async def invoke(_live, handler):
        item = await handler(3, {3: server}, {3: "u"}, _live)
        sbs.record_result(_live, item)

    with patch(
        "server.application.services.server_batch_service._run_with_semaphore",
        new_callable=AsyncMock,
        side_effect=invoke,
    ):
        with patch(
            "server.application.services.files_sudoers_service.install_nexus_files_sudoers",
            new_callable=AsyncMock,
            return_value={"ok": True, "action": "patched"},
        ):
            with patch(
                "server.application.server_batch_common.detect_and_save_target_path",
                new_callable=AsyncMock,
                return_value={"success": False, "error": "未找到 workerman.bat"},
            ):
                await _run_onboard(live)

    assert live["results"]["3"]["success"] is True
    assert "www/wwwroot" in live["results"]["3"]["stdout"]
