"""YakPanel - FTP service (Pure-FTPd via pure-pw)"""
import os
import subprocess
from app.core.config import get_runtime_config


def _run_pure_pw(args: str, stdin: str | None = None) -> tuple[str, str]:
    """Run pure-pw command. Returns (stdout, stderr)."""
    try:
        r = subprocess.run(
            f"pure-pw {args}",
            shell=True,
            input=stdin,
            capture_output=True,
            text=True,
            timeout=10,
        )
        return r.stdout or "", r.stderr or ""
    except FileNotFoundError:
        return "", "pure-pw not found"
    except subprocess.TimeoutExpired:
        return "", "Timed out"


def create_ftp_user(name: str, password: str, path: str) -> tuple[bool, str]:
    """Create Pure-FTPd virtual user via pure-pw."""
    if not all(c.isalnum() or c in "._-" for c in name):
        return False, "Invalid username"
    if ".." in path:
        return False, "Invalid path"
    path_abs = os.path.abspath(path)
    cfg = get_runtime_config()
    www_root = os.path.abspath(cfg["www_root"])
    if not (path_abs == www_root or path_abs.startswith(www_root + os.sep)):
        return False, "Path must be under www_root"
    os.makedirs(path_abs, exist_ok=True)
    # pure-pw useradd prompts for password twice; pipe it
    stdin = f"{password}\n{password}\n"
    out, err = _run_pure_pw(
        f'useradd {name} -u www-data -d "{path_abs}" -m',
        stdin=stdin,
    )
    if err and "error" in err.lower() and "already exists" not in err.lower():
        return False, err.strip() or out.strip()
    out2, err2 = _run_pure_pw("mkdb")
    if err2 and "error" in err2.lower():
        return False, err2.strip() or out2.strip()
    return True, "FTP user created"


def delete_ftp_user(name: str) -> tuple[bool, str]:
    """Delete Pure-FTPd virtual user."""
    if not all(c.isalnum() or c in "._-" for c in name):
        return False, "Invalid username"
    out, err = _run_pure_pw(f'userdel {name} -m')
    if err and "error" in err.lower():
        return False, err.strip() or out.strip()
    return True, "FTP user deleted"


def update_ftp_password(name: str, new_password: str) -> tuple[bool, str]:
    """Change Pure-FTPd user password."""
    if not all(c.isalnum() or c in "._-" for c in name):
        return False, "Invalid username"
    stdin = f"{new_password}\n{new_password}\n"
    out, err = _run_pure_pw(f'passwd {name} -m', stdin=stdin)
    if err and "error" in err.lower():
        return False, err.strip() or out.strip()
    return True, "Password updated"
