#!/usr/bin/env python3
"""Diagnose and fix NEXT_PUBLIC_* URLs to HTTPS on production."""
from __future__ import annotations

import base64
import paramiko

APP_HOST, APP_USER, APP_PASS = "192.168.10.162", "morteza", "Moli@5404"
NGX_HOST, NGX_USER, NGX_PASS = "192.168.10.156", "torbatyaruser", "Moli@5404"
REMOTE = "/home/morteza/torbatyar"

HTTPS_KEYS = {
    "NEXT_PUBLIC_BACKEND_URL": "https://api.torbatyar.ir",
    "NEXT_PUBLIC_API_BASE_URL": "https://api.torbatyar.ir",
    "NEXT_PUBLIC_IDENTITY_API_URL": "https://identity.torbatyar.ir",
    "NEXT_PUBLIC_KEYCLOAK_URL": "https://auth.torbatyar.ir",
    "NEXT_PUBLIC_ACCOUNTING_API_URL": "https://accounting.torbatyar.ir",
    "KEYCLOAK_PUBLIC_URL": "https://auth.torbatyar.ir",
    "FRONTEND_CALLBACK_URL": "https://torbatyar.ir/auth/callback",
}


def connect(host, user, password):
    c = paramiko.SSHClient()
    c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    c.connect(host, username=user, password=password, timeout=30, allow_agent=False, look_for_keys=False)
    return c


def run(c, cmd, password=None, timeout=600):
    b64 = base64.b64encode(cmd.encode()).decode()
    if password:
        full = f"echo {password!r} | sudo -S -p '' bash -c 'echo {b64} | base64 -d | bash'"
    else:
        full = f"bash -lc 'echo {b64} | base64 -d | bash'"
    print("\n>>>", cmd[:200].replace("\n", " | "))
    _, out, err = c.exec_command(full, timeout=timeout, get_pty=True)
    text = (out.read() + err.read()).decode("utf-8", "replace")
    code = out.channel.recv_exit_status()
    print(text[-5000:].encode("ascii", "replace").decode("ascii"))
    return code, text


def main() -> int:
    # Public smoke first
    ngx = connect(NGX_HOST, NGX_USER, NGX_PASS)
    try:
        run(
            ngx,
            """
echo === identity https ===
curl -sI https://identity.torbatyar.ir/health | head -n 12 || true
curl -s https://identity.torbatyar.ir/health || curl -sk https://identity.torbatyar.ir/health || echo FAIL
echo
echo === identity http ===
curl -sI http://identity.torbatyar.ir/health | head -n 12 || true
""",
            password=NGX_PASS,
            timeout=60,
        )
    finally:
        ngx.close()

    app = connect(APP_HOST, APP_USER, APP_PASS)
    try:
        keys_repr = repr(HTTPS_KEYS)
        code, _ = run(
            app,
            f"""
set -e
cd {REMOTE}
echo === BEFORE ===
grep -E 'NEXT_PUBLIC_|KEYCLOAK_PUBLIC_URL|FRONTEND_CALLBACK' .env || true
python3 - <<'PY'
from pathlib import Path
p = Path('.env')
text = p.read_text(encoding='utf-8') if p.exists() else ''
keys = {keys_repr}
lines = text.splitlines()
seen = set()
out = []
for line in lines:
    if not line.strip() or line.lstrip().startswith('#') or '=' not in line:
        out.append(line)
        continue
    k = line.split('=', 1)[0].strip()
    if k in keys:
        out.append(f'{{k}}={{keys[k]}}')
        seen.add(k)
    else:
        # also rewrite accidental http://*.torbatyar.ir public URLs
        if k.startswith('NEXT_PUBLIC_') or k in ('KEYCLOAK_PUBLIC_URL', 'FRONTEND_CALLBACK_URL', 'CORS_ORIGINS'):
            v = line.split('=', 1)[1]
            v2 = v.replace('http://api.torbatyar.ir', 'https://api.torbatyar.ir') \\
                 .replace('http://identity.torbatyar.ir', 'https://identity.torbatyar.ir') \\
                 .replace('http://auth.torbatyar.ir', 'https://auth.torbatyar.ir') \\
                 .replace('http://torbatyar.ir', 'https://torbatyar.ir') \\
                 .replace('http://www.torbatyar.ir', 'https://www.torbatyar.ir') \\
                 .replace('http://accounting.torbatyar.ir', 'https://accounting.torbatyar.ir')
            out.append(f'{{k}}={{v2}}')
            seen.add(k)
            continue
        out.append(line)
for k, v in keys.items():
    if k not in seen:
        out.append(f'{{k}}={{v}}')
p.write_text('\\n'.join(out).rstrip() + '\\n', encoding='utf-8')
print('env_patched')
PY
echo === AFTER ===
grep -E 'NEXT_PUBLIC_|KEYCLOAK_PUBLIC_URL|FRONTEND_CALLBACK' .env || true
# recreate frontend so Next picks new NEXT_PUBLIC_* at process start
docker compose up -d --force-recreate frontend identity-access-service
sleep 10
docker compose exec -T frontend printenv | grep -E 'NEXT_PUBLIC_IDENTITY|NEXT_PUBLIC_BACKEND|NEXT_PUBLIC_KEYCLOAK|NEXT_PUBLIC_ACCOUNTING' || true
docker compose ps frontend identity-access-service
curl -sf http://127.0.0.1:8001/health || echo IDENTITY_LOCAL_FAIL
echo
curl -s -o /dev/null -w 'accounting_page=%{{http_code}}\\n' http://127.0.0.1:3000/accounting
""",
            password=APP_PASS,
            timeout=300,
        )
        if code != 0:
            raise RuntimeError("fix failed")
    finally:
        app.close()
    print("\n=== DONE ===")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
