#!/usr/bin/env python3
"""pppd ip-up hook (ADR-0018 b4) — shape a Vendora PPPoE-server session + record
it for the concentrator's reaper.

pppd runs every script in /etc/ppp/ip-up.d/ for EVERY ppp session — including a
WAN PPPoE *client* if the box uses PPPoE for its uplink (ADR-0008). So we scope
to OUR sessions: if PEERNAME isn't a pppoe_accounts username, exit 0 and do
nothing (Open-Q #7 — coexist with a WAN PPPoE client).

pppd args: $1=iface $2=tty $3=speed $4=local-ip $5=remote-ip $6=ipparam
pppd env : PEERNAME (the authenticated username), PPPD_PID (this session's pppd).
"""
import os
import sys

sys.path.insert(0, "/opt/vendora_sbc/services")
try:
    from common import pppoe_accounts as pa
    from common import pppoe_config as pc
    from common import tc as vtc
except Exception:
    sys.exit(0)  # Vendora not present / import hiccup — never break pppd

iface = sys.argv[1] if len(sys.argv) > 1 else os.environ.get("IFNAME", "")
peer = os.environ.get("PEERNAME", "")
if not iface or not peer:
    sys.exit(0)

acct = pa.get_account(peer)
if not acct:
    sys.exit(0)  # not a Vendora PPPoE account (e.g. a WAN PPPoE client) — ignore

# Shape the session to the account's caps (0 = unlimited; best-effort).
try:
    vtc.shape_ppp_iface(iface, acct.get("down_kbps") or 0, acct.get("up_kbps") or 0)
except Exception:
    pass


def _pppd_pid():
    """The session's pppd pid: PPPD_PID env first, else pppd's per-unit pid file.
    The reaper SIGTERMs this to drop a suspended/expired session."""
    p = (os.environ.get("PPPD_PID") or "").strip()
    if p.isdigit():
        return p
    for d in ("/var/run", "/run"):
        try:
            with open(os.path.join(d, iface + ".pid")) as f:
                v = f.read().split()[0].strip()
                if v.isdigit():
                    return v
        except Exception:
            pass
    return "0"


# Record SESSION_DIR/<iface> = "<username> <pid>" for the runner's reaper.
try:
    os.makedirs(pc.SESSION_DIR, exist_ok=True)
    with open(os.path.join(pc.SESSION_DIR, iface), "w") as f:
        f.write(peer + " " + _pppd_pid())
except Exception:
    pass

sys.exit(0)
