#!/usr/bin/env python3
"""Install internal nginx listener for mail API and update production env."""
import re
import sys
from pathlib import Path

import paramiko

VPS_HOST = "65.75.210.95"
VPS_USER = "root"
VPS_PASS = "%8qd6oJx%PBB"
REMOTE_WEB = "/var/www/servidor/web"
LOCAL_DIR = Path(__file__).resolve().parent.parent
NGINX_LOCAL = LOCAL_DIR / "Servidor" / "mail" / "nginx-mail-internal.conf"
NGINX_REMOTE = "/etc/nginx/sites-available/mail-internal.conf"
MAIL_URL = "http://127.0.0.1:8091/mail/send.php"


def run(client, cmd: str, timeout: int = 60) -> 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_url = False
    for line in lines:
        if line.startswith("EMAIL_API_URL="):
            out.append(f"EMAIL_API_URL={MAIL_URL}")
            seen_url = True
        elif line.startswith("EMAIL_API_HOST="):
            continue
        else:
            out.append(line)
    if not seen_url:
        out.append(f"EMAIL_API_URL={MAIL_URL}")
    return "\n".join(out).rstrip() + "\n"


def main() -> int:
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(VPS_HOST, username=VPS_USER, password=VPS_PASS, timeout=20)

    sftp = client.open_sftp()
    sftp.put(str(NGINX_LOCAL), NGINX_REMOTE)
    sftp.close()
    print("Uploaded nginx mail-internal config")

    run(client, f"ln -sf {NGINX_REMOTE} /etc/nginx/sites-enabled/mail-internal.conf")
    nginx = run(client, "nginx -t && systemctl reload nginx")
    sys.stdout.buffer.write(nginx.encode("utf-8", errors="replace"))
    if "successful" not in nginx and "syntax is ok" not in nginx.lower():
        print("nginx test failed")
        client.close()
        return 1

    env_path = f"{REMOTE_WEB}/.env.production"
    patched = patch_env(run(client, f"cat {env_path}"))
    with client.open_sftp().file(env_path, "w") as f:
        f.write(patched)
    print(f"Updated {env_path} -> EMAIL_API_URL={MAIL_URL}")

    key_match = re.search(
        r"'api_key'\s*=>\s*'([^']+)'",
        run(client, "cat /var/www/servidor/mail/config.php"),
    )
    key = key_match.group(1) if key_match else ""

    curl_test = run(
        client,
        f"curl -sS -m 20 -w '\\ncode=%{{http_code}}\\n' "
        f"-X POST '{MAIL_URL}' "
        f"-d 'key={key}&email=unplayer3467@gmail.com&code=123456&type=register'",
    )
    print("curl:", curl_test.strip())

    node_test = run(
        client,
        f"node -e \"fetch('{MAIL_URL}',{{method:'POST',headers:{{'Content-Type':'application/x-www-form-urlencoded'}},"
        f"body:new URLSearchParams({{key:'{key}',email:'unplayer3467@gmail.com',code:'123456',type:'register'}})}})"
        f".then(async r=>console.log('node',r.status,await r.text())).catch(e=>console.log('node err',e.message));\"",
        timeout=30,
    )
    print(node_test.strip())

    run(
        client,
        f"cd {REMOTE_WEB} && pm2 restart urbangamers backup-pinger --update-env && pm2 save",
        timeout=60,
    )
    print("PM2 restarted")

    client.close()
    return 0 if "ok" in curl_test and "ok" in node_test else 1


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