"""Shared Nexus files sudoers template and remote install helpers."""

from __future__ import annotations

import asyncio
import shlex
import textwrap

from server.domain.models import Server
from server.infrastructure.ssh.asyncssh_pool import exec_ssh_command, ssh_pool
from server.infrastructure.database.crypto import decrypt_value
from server.infrastructure.ssh.remote_shell import exec_ssh_command_with_fallback

NEXUS_FILES_SUDOERS_PATH = "/etc/sudoers.d/nexus-files"


def build_nexus_files_sudoers(ssh_user: str) -> str:
    """Return sudoers.d fragment for file manager + rsync push elevation."""
    user = (ssh_user or "deploy").strip() or "deploy"
    return textwrap.dedent(f"""\
        # nexus-files: configured by Nexus (file manager + rsync push)
        {user} ALL=(root) NOPASSWD: \\
            /bin/ls, /usr/bin/ls, \\
            /bin/cat, /usr/bin/cat, \\
            /usr/bin/tee, /bin/tee, \\
            /bin/mkdir, /usr/bin/mkdir, \\
            /bin/cp, /usr/bin/cp, \\
            /bin/mv, /usr/bin/mv, \\
            /bin/rm, /usr/bin/rm, \\
            /bin/chmod, /usr/bin/chmod, \\
            /bin/chown, /usr/bin/chown, \\
            /bin/bash, /usr/bin/bash, \\
            /usr/bin/rsync, /bin/rsync
    """)


async def probe_rsync_sudo(server: Server, *, timeout: int = 15) -> bool:
    """True when ``sudo -n rsync`` works on the target."""
    ssh_user = (server.username or "root").strip() or "root"
    if ssh_user == "root":
        result = await exec_ssh_command(server, "rsync --version", timeout=timeout)
        return result.get("exit_code") == 0
    result = await exec_ssh_command(server, "sudo -n rsync --version", timeout=timeout)
    return result.get("exit_code") == 0


async def _write_sudoers_with_password(
    server: Server,
    content: str,
    sudoers_path: str,
    plain_password: str,
) -> dict:
    write_cmd = (
        f"printf %s {shlex.quote(content)}"
        f" | sudo -S tee {shlex.quote(sudoers_path)} > /dev/null"
        f" && sudo chmod 440 {shlex.quote(sudoers_path)}"
        f" && sudo visudo -cf {shlex.quote(sudoers_path)}"
    )
    conn = None
    try:
        conn = await ssh_pool.acquire(server)
        result = await asyncio.wait_for(
            conn.run(write_cmd, input=plain_password + "\n", timeout=20),
            timeout=25,
        )
        exit_code = result.exit_status if result.exit_status is not None else -1
        stderr_out = (result.stderr or "").strip()
        stdout_out = (result.stdout or "").strip()
        if exit_code != 0:
            detail = stderr_out or stdout_out or f"exit {exit_code}"
            return {"ok": False, "action": "password_sudo_failed", "detail": detail[:500]}
        return {"ok": True, "action": "patched_password_sudo"}
    finally:
        if conn is not None:
            await ssh_pool.release(server.id)


async def install_nexus_files_sudoers(server: Server, *, dry_run: bool = False) -> dict:
    """Ensure ``/etc/sudoers.d/nexus-files`` includes rsync (and file ops whitelist).

    Returns ``{ok, action, server_id, server_name, ssh_user, detail?}``.
    """
    ssh_user = (server.username or "root").strip() or "root"
    base = {
        "server_id": server.id,
        "server_name": server.name,
        "ssh_user": ssh_user,
    }

    if ssh_user == "root":
        return {**base, "ok": True, "action": "skip_root"}

    if await probe_rsync_sudo(server):
        return {**base, "ok": True, "action": "already_ok"}

    if dry_run:
        return {**base, "ok": True, "action": "would_patch"}

    content = build_nexus_files_sudoers(ssh_user)
    sudoers_path = NEXUS_FILES_SUDOERS_PATH

    if server.password:
        plain = decrypt_value(server.password)
        outcome = await _write_sudoers_with_password(server, content, sudoers_path, plain)
        if not outcome["ok"]:
            return {**base, **outcome}
        if await probe_rsync_sudo(server):
            return {**base, **outcome}
        return {
            **base,
            "ok": False,
            "action": "written_but_rsync_probe_failed",
            "detail": "sudoers 已写入但 sudo -n rsync 仍失败",
        }

    write_inner = (
        f"printf %s {shlex.quote(content)}"
        f" | tee {shlex.quote(sudoers_path)} > /dev/null"
        f" && chmod 440 {shlex.quote(sudoers_path)}"
        f" && visudo -cf {shlex.quote(sudoers_path)}"
    )
    result = await exec_ssh_command_with_fallback(server, write_inner, timeout=30)
    if result.get("exit_code") != 0:
        detail = (result.get("stderr") or result.get("stdout") or "")[:500]
        return {
            **base,
            "ok": False,
            "action": "nopasswd_write_failed",
            "detail": detail or "无法写入 sudoers（需存储 SSH 密码或已配置 bash 免密 sudo）",
        }

    if await probe_rsync_sudo(server):
        return {**base, "ok": True, "action": "patched_nopasswd"}

    return {
        **base,
        "ok": False,
        "action": "written_but_rsync_probe_failed",
        "detail": "sudoers 已写入但 sudo -n rsync 仍失败，请检查 visudo 与白名单路径",
    }
