#!/usr/bin/env python3
import re
import subprocess
import sys
from pathlib import Path

INSTANCE = sys.argv[1] if len(sys.argv) > 1 else "mgts-main"

BASE = Path("/opt/router-ops")
INSTANCE_DIR = BASE / "instances" / INSTANCE
EGRESS_YML = INSTANCE_DIR / "egress.yml"

PVE = "pve-mgts"
PVE_KEY = "/root/.ssh/pve_to_openwrt_mgts_ed25519"
VM101 = "10.71.100.2"

if not EGRESS_YML.exists():
    print(f"ERROR: missing {EGRESS_YML}", file=sys.stderr)
    sys.exit(1)


def header(title: str) -> None:
    print()
    print("################################################################")
    print(f"### {title}")
    print("################################################################")
    print()


def parse_slots(text: str):
    slots = []
    in_slots = False
    current = None

    for line in text.splitlines():
        if re.match(r"^\s*slots:\s*$", line):
            in_slots = True
            continue

        if in_slots and re.match(r"^\s{2}[a-zA-Z_].*:", line) and not line.strip().startswith("- "):
            if current:
                slots.append(current)
                current = None
            break

        if not in_slots:
            continue

        m = re.match(r"^\s*-\s*id:\s*(.+?)\s*$", line)
        if m:
            if current:
                slots.append(current)
            current = {"id": clean(m.group(1))}
            continue

        if current:
            m = re.match(r"^\s*([a-zA-Z_]+):\s*(.+?)\s*$", line)
            if m:
                current[m.group(1)] = clean(m.group(2))

    if current:
        slots.append(current)

    return slots


def clean(value: str) -> str:
    value = value.strip()
    if value.startswith('"') and value.endswith('"'):
        value = value[1:-1]
    if value.startswith("'") and value.endswith("'"):
        value = value[1:-1]
    return value


def run_local(cmd):
    p = subprocess.run(cmd, text=True, capture_output=True)
    if p.stdout:
        print(p.stdout, end="")
    if p.stderr:
        print(p.stderr, end="", file=sys.stderr)
    print(f"\nrc={p.returncode}")


def vm101(script: str) -> None:
    cmd = [
        "ssh",
        "-o", "BatchMode=yes",
        "-o", "ConnectTimeout=10",
        PVE,
        f"ssh -i {PVE_KEY} -o BatchMode=yes -o ConnectTimeout=8 root@{VM101} 'sh -s'"
    ]
    p = subprocess.run(cmd, input=script, text=True, capture_output=True)
    if p.stdout:
        print(p.stdout, end="")
    if p.stderr:
        print(p.stderr, end="", file=sys.stderr)
    print(f"\nrc={p.returncode}")


egress_text = EGRESS_YML.read_text()
slots = parse_slots(egress_text)

header("ROUTER EGRESS PLAN")
print(f"INSTANCE={INSTANCE}")
print(f"INSTANCE_DIR={INSTANCE_DIR}")
print(f"EGRESS_YML={EGRESS_YML}")
print("MODE=DRY_RUN_ONLY")
print("REMOTE_CHANGES=NO")

header("EXPECTED SLOTS FROM PROFILE")
for s in slots:
    print(
        f"{s.get('id',''):<12} "
        f"iface={s.get('iface',''):<6} "
        f"table={s.get('table',''):<4} "
        f"fwmark={s.get('fwmark',''):<6} "
        f"provider={s.get('provider',''):<12} "
        f"role={s.get('role',''):<8} "
        f"weight={s.get('weight','')}"
    )

header("VM101 CURRENT BASIC STATE")
vm101(r'''
date
uptime
echo
ip -br addr
echo
ip route
echo
ip rule
''')

header("VM101 LEGACY AUTOMATION FREEZE CHECK")
vm101(r'''
echo "=== crontab ==="
crontab -l 2>/dev/null || true
echo
echo "=== hotplug iface ==="
ls -la /etc/hotplug.d/iface
echo
echo "=== legacy processes ==="
ps w | grep -E 'vpn-egress-manager|hmn-refresh|hmn-pool|hmn-vpn-user' | grep -v grep || true
''')

header("VM101 CURRENT EGRESS INTERFACE SUMMARY")
vm101(r'''
for i in vpn1 vpn2 vpn3 vpn4 vpn5 vpn_user vpn_test; do
  echo "--- $i ---"
  uci -q get network.$i.proto 2>/dev/null | sed 's/^/proto=/'
  uci -q get network.$i.auto 2>/dev/null | sed 's/^/auto=/'
  uci -q get network.$i.disabled 2>/dev/null | sed 's/^/disabled=/'
  uci -q get network.$i.addresses 2>/dev/null | sed 's/^/addresses=/'
  uci -q get network.$i.hmn_role 2>/dev/null | sed 's/^/hmn_role=/'
  uci -q get network.$i.hmn_endpoint 2>/dev/null | sed 's/^/hmn_endpoint=/'
  ip -br addr show dev $i 2>/dev/null || true
done
''')

header("VM101 FIREWALL VPN_OUT SUMMARY")
vm101(r'''
uci show firewall | grep -E 'vpn_out|vpn1|vpn2|vpn3|vpn4|vpn5|vpn_user|vpn_test|forwarding.*vpn_in|dest=.vpn_out.|src=.vpn_in.' || true
''')

header("VM101 TABLE/ROUTE LEGACY SUMMARY")
vm101(r'''
echo "=== rt_tables ==="
cat /etc/iproute2/rt_tables 2>/dev/null || true
echo
echo "=== table 200 ==="
ip route show table 200 2>/dev/null || true
echo
echo "=== candidate new tables 201-205 ==="
for t in 201 202 203 204 205; do
  echo "--- table $t ---"
  ip route show table $t 2>/dev/null || true
done
''')

header("VM101 HMN CANDIDATE POOL SUMMARY")
vm101(r'''
echo "=== hmn dirs ==="
ls -la /root/hmn 2>/dev/null || true
echo
echo "=== latest config count ==="
find /root/hmn/configs/awg1/latest -maxdepth 1 -type f -name "*.conf" 2>/dev/null | wc -l
echo
echo "=== latest configs sample ==="
find /root/hmn/configs/awg1/latest -maxdepth 1 -type f -name "*.conf" 2>/dev/null | sed 's#.*/##' | sort | sed -n '1,80p'
echo
echo "=== selected/cache files ==="
find /root/hmn -maxdepth 3 -type f 2>/dev/null | grep -Ei 'selected|working|candidate|status|latest.tsv|pool|health|score' | sort | sed -n '1,120p'
''')

header("DRY-RUN DECISION")
print("No changes applied.")
print()
print("Expected next implementation steps:")
print("1. Create local egress tool skeleton under product/egress/bin.")
print("2. Create VM101-side /opt/router-ops/egress runtime directory.")
print("3. Add read-only slot status command.")
print("4. Add apply steps only after explicit confirmation.")
print()
print("Safety constraints still active:")
print("- do not touch VM101 WAN eth0")
print("- do not touch VM101 DNAT 51820/51830")
print("- do not touch VM100 wg_remote/wg_paid")
print("- do not globally restart network")
print("- do not flush ip rules")
