#!/usr/bin/env python3
"""本机/本地服务器一键部署中控（git pull + 构建 + pm2 reload）。

环境变量（可选）:
  CONTROL_ROOT   默认 /opt/eth_hedge_sim（与策略机同仓）或本机仓库根
  CONTROL_HOST   若设置则 SSH 远程执行；否则在本机执行
  CONTROL_USER   默认 root
  CONTROL_PASS   SSH 密码（远程时必填）
  REPO_URL       默认 https://git.bz121.com/dekun/eth_hedge_sim.git
"""

from __future__ import annotations

import os
import subprocess
import sys
from pathlib import Path

HOST = os.environ.get("CONTROL_HOST", "").strip()
USER = os.environ.get("CONTROL_USER", "root")
PASSWORD = os.environ.get("CONTROL_PASS", "")
ROOT = os.environ.get("CONTROL_ROOT", "").strip()
REPO = os.environ.get("REPO_URL", "https://git.bz121.com/dekun/eth_hedge_sim.git")


def _default_root() -> Path:
    # scripts/deploy_control.py -> repo root
    return Path(__file__).resolve().parents[1]


def local_update(root: Path) -> int:
    script = root / "control" / "deploy" / "update.sh"
    if not script.is_file():
        print(f"missing {script}", file=sys.stderr)
        return 2
    if os.name == "nt":
        print("Run on Linux local server, or set CONTROL_HOST for SSH.", file=sys.stderr)
        return 2
    env = {**os.environ, "DEBIAN_FRONTEND": "noninteractive"}
    proc = subprocess.run(["bash", str(script)], cwd=str(root), env=env)
    return int(proc.returncode)


def remote_update(root: str) -> int:
    try:
        import paramiko
    except ImportError:
        print("pip install paramiko", file=sys.stderr)
        return 2
    if not PASSWORD:
        print("Set CONTROL_PASS for remote deploy.", file=sys.stderr)
        return 2
    remote = f"""
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
if [[ ! -d '{root}/.git' ]]; then
  mkdir -p "$(dirname '{root}')"
  git clone '{REPO}' '{root}'
fi
bash '{root}/control/deploy/update.sh'
curl -fsS http://127.0.0.1:5160/health || true
"""
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    print(f"connecting {USER}@{HOST} ...")
    client.connect(HOST, username=USER, password=PASSWORD, timeout=30)
    print("running control update ...")
    _stdin, stdout, stderr = client.exec_command(remote, get_pty=True)
    while True:
        chunk = stdout.read(1024)
        if not chunk:
            break
        text = chunk.decode("utf-8", errors="replace") if isinstance(chunk, bytes) else chunk
        print(text, end="", flush=True)
    err_raw = stderr.read()
    err = err_raw.decode("utf-8", errors="replace") if isinstance(err_raw, bytes) else err_raw
    code = stdout.channel.recv_exit_status()
    if err:
        print(err, file=sys.stderr)
    client.close()
    print(f"exit={code}")
    return int(code)


def main() -> int:
    if HOST:
        root = ROOT or "/opt/eth_hedge_sim"
        return remote_update(root)
    root = Path(ROOT) if ROOT else _default_root()
    return local_update(root)


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