"""Tests for rsync push sudo elevation (non-root auto_sudo policy)."""

from __future__ import annotations

import pytest

from server.domain.models import Server
from server.utils.rsync_elevation import (
    RSYNC_SUDO_RECEIVER_PATH,
    is_root_ssh_user,
    rsync_elevation_log_hint,
    rsync_receiver_path_for_push,
)


def test_root_ssh_skips_sudo_rsync():
    server = Server(name="t", domain="1.2.3.4", username="root")
    assert is_root_ssh_user(server) is True
    assert rsync_receiver_path_for_push(server) is None
    assert rsync_elevation_log_hint(server) is None


def test_non_root_default_auto_sudo_uses_sudo_rsync():
    """Unset extra_attrs → normalize to auto_sudo → sudo rsync (Ubuntu/deploy 默认)."""
    server = Server(name="t", domain="1.2.3.4", username="ubuntu")
    assert rsync_receiver_path_for_push(server) == RSYNC_SUDO_RECEIVER_PATH
    assert rsync_elevation_log_hint(server) == "rsync=sudo"


def test_non_root_always_sudo_uses_sudo_rsync():
    server = Server(
        name="t",
        domain="1.2.3.4",
        username="deploy",
        extra_attrs={"files_elevation": "always_sudo"},
    )
    assert rsync_receiver_path_for_push(server) == RSYNC_SUDO_RECEIVER_PATH


def test_non_root_off_disables_sudo_rsync():
    server = Server(
        name="t",
        domain="1.2.3.4",
        username="deploy",
        extra_attrs={"files_elevation": "off"},
    )
    assert rsync_receiver_path_for_push(server) is None
    assert rsync_elevation_log_hint(server) is None


@pytest.mark.asyncio
async def test_rsync_push_passes_sudo_path_for_non_root(monkeypatch, tmp_path):
    import asyncio

    from server.application.services import sync_engine_v2 as se

    source = tmp_path / "src"
    source.mkdir()
    (source / "a.txt").write_text("hi", encoding="utf-8")

    server = Server(
        name="t",
        domain="127.0.0.1",
        username="ubuntu",
        ssh_key_path="/nonexistent/key",
    )

    captured: list[str | None] = []

    async def fake_execute(_server, _src, _dest, **kwargs):
        captured.append(kwargs.get("rsync_receiver_path"))
        return {"exit_code": 0, "stdout": "", "stderr": ""}

    monkeypatch.setattr(se, "_execute_rsync_push", fake_execute)

    result = await se._rsync_push(server, str(source), "/www/wwwroot/site")
    assert captured == [RSYNC_SUDO_RECEIVER_PATH]
    assert result["elevated"] is True
