#!/usr/bin/env python3
"""Fix mail permissions, env, rebuild web, restart PM2."""
import re
import sys
from pathlib import Path

import paramiko
from scp import SCPClient

VPS_HOST = "65.75.210.95"
VPS_USER = "root"
VPS_PASS = "%8qd6oJx%PBB"
REMOTE_WEB = "/var/www/servidor/web"
REMOTE_MAIL = "/var/www/servidor/mail"
LOCAL_DIR = Path(__file__).resolve().parent.parent
MAIL_FILES = ["config.php", "template.php", "send.php", "smtp.php"]

ENV_PATCH = {
    "EMAIL_API_URL": "http://127.0.0.1/mail/send.php",
    "EMAIL_API_HOST": "models.hostlanty.com",
}


def run(client, cmd: str, timeout: int = 120) -> str:
    _, stdout, stderr = client.exec_command(cmd, timeout=timeout)
    return (stdout.read() + stderr.read()).decode("utf-8", errors="replace")


def patch_env(content: str) -> str:
    lines = content.splitlines()
    out: list[str] = []
    seen: set[str] = set()
    for line in lines:
        matched = False
        for key, value in ENV_PATCH.items():
            if line.startswith(f"{key}="):
                out.append(f"{key}={value}")
                seen.add(key)
                matched = True
                break
        if not matched:
            out.append(line)
    if "EMAIL_API_URL" not in seen:
        out.append(f"EMAIL_API_URL={ENV_PATCH['EMAIL_API_URL']}")
    if "EMAIL_API_HOST" not in seen:
        out.append(f"EMAIL_API_HOST={ENV_PATCH['EMAIL_API_HOST']}")
    return "\n".join(out).rstrip() + "\n"


def main() -> int:
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    print(f"Connecting to {VPS_HOST}...")
    client.connect(VPS_HOST, username=VPS_USER, password=VPS_PASS, timeout=20)

    mail_local = LOCAL_DIR / "Servidor" / "mail"
    run(client, f"mkdir -p {REMOTE_MAIL}", timeout=15)
    with SCPClient(client.get_transport()) as scp:
        for name in MAIL_FILES:
            local_file = mail_local / name
            if local_file.is_file():
                scp.put(str(local_file), f"{REMOTE_MAIL}/{name}")
                print(f"  mail: {name}")

    print("Fixing mail permissions...")
    run(
        client,
        f"chown root:www-data {REMOTE_MAIL}/config.php && "
        f"chmod 640 {REMOTE_MAIL}/config.php && "
        f"chmod 644 {REMOTE_MAIL}/*.php",
        timeout=15,
    )

    env_path = f"{REMOTE_WEB}/.env.production"
    current = run(client, f"cat {env_path} 2>/dev/null", timeout=15)
    patched = patch_env(current)
    sftp = client.open_sftp()
    with sftp.file(env_path, "w") as f:
        f.write(patched)
    sftp.close()
    print("Patched .env.production (EMAIL_API_URL + EMAIL_API_HOST)")

    print("Uploading web + building...")
    sys.path.insert(0, str(LOCAL_DIR))
    from deploy_vps import upload_project  # noqa: E402

    with SCPClient(client.get_transport()) as scp:
        upload_project(scp, client)

    print(run(client, f"cd {REMOTE_WEB} && npm run build 2>&1 | tail -20", timeout=600))

    print("Restarting PM2...")
    run(
        client,
        f"cd {REMOTE_WEB} && rm -rf .next/cache && pm2 restart urbangamers backup-pinger --update-env && pm2 save",
        timeout=60,
    )

    key_match = re.search(r"'api_key'\s*=>\s*'([^']+)'", run(client, f"cat {REMOTE_MAIL}/config.php", timeout=10))
    key = key_match.group(1) if key_match else "invalid"
    test = run(
        client,
        f"curl -sS -m 30 -w '\\ncode=%{{http_code}}\\n' "
        f"-H 'Host: models.hostlanty.com' "
        f"-X POST 'http://127.0.0.1/mail/send.php' "
        f"-d 'key={key}&email=test@example.com&code=654321&type=register'",
        timeout=40,
    )
    sys.stdout.buffer.write(test.encode("utf-8", errors="replace"))
    sys.stdout.buffer.write(b"\n")

    client.close()
    return 0 if "ok" in test and "code=200" in test else 1


if __name__ == "__main__":
    sys.exit(main())
