#!/usr/bin/env bash
# Desk AV + security status · one sheet · no polkit
# Combines BGL · inject · SPV AV · heuristics · mail identity · Claws pins · site optional
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
OUT="$ROOT/out"
HEU=""  # linear KNOW · no ESTABLISH stamp
export SUDO_PASS="${SUDO_PASS:-mememe}"
export SUDO_ASKPASS="${SUDO_ASKPASS:-$ROOT/Build/sudo-askpass.sh}"
JSON_OUT="$OUT/desk_security_status.json"
TXT_OUT="$OUT/DESK_SECURITY.txt"

say() { echo "$*"; }

# thrash public only · desk Apache 80/443 on own IPs not thrash
# shellcheck source=h7-desk-ports.lib.sh
. "$(cd "$(dirname "$0")" && pwd)/h7-desk-ports.lib.sh"
pub=$(count_thrash_public | tr -d ' ')
loc=$(ss -ltn 2>/dev/null | awk 'NR>1 && $4 ~ /127\.|::1/ {c++} END{print c+0}')
xdg=$(pgrep -c xdg-open 2>/dev/null || true); xdg=${xdg:-0}; xdg=${xdg//[^0-9]/}; xdg=${xdg:-0}
pkexec_n=$(pgrep -c pkexec 2>/dev/null || true); pkexec_n=${pkexec_n:-0}; pkexec_n=${pkexec_n//[^0-9]/}; pkexec_n=${pkexec_n:-0}

python3 - <<PY
import json, time, re, os
from pathlib import Path
out = Path("$OUT")
heu_path = Path("$HEU")
id_path = Path.home() / ".config/biggrinrtx/identity.json"
claws = Path.home() / ".claws-mail/accountrc"
pass_file = Path.home() / ".config/biggrinrtx/titan.pass"
xai_key = Path.home() / ".config/biggrinrtx/xai.key"

def load(p):
    try:
        return json.loads(Path(p).read_text())
    except Exception:
        return None

bgl = load(out / "bgl_secure.json") or {}
inj = load(out / "av_inject_latest.json") or load(out / "av_inject.json") or {}
av = load(out / "spv_antivirus.json") or {}
est = {}  # no establish · we always KNOW · linear
ident = load(id_path) or {}

# claws pins
claws_ok = False
claws_bits = {}
if claws.is_file():
    t = claws.read_text(errors="replace")
    def g(k):
        m = re.search(rf"^{re.escape(k)}=(.*)$", t, re.M)
        return m.group(1).strip() if m else None
    claws_bits = {
        "ssl_imap": g("ssl_imap"),
        "ssl_smtp": g("ssl_smtp"),
        "imap_port": g("imap_port"),
        "smtp_port": g("smtp_port"),
        "receive_server": g("receive_server"),
        "smtp_server": g("smtp_server"),
        "user_id": g("user_id"),
        "address": g("address"),
    }
    claws_ok = (
        claws_bits.get("ssl_imap") == "1"
        and claws_bits.get("ssl_smtp") == "1"
        and claws_bits.get("imap_port") == "993"
        and claws_bits.get("smtp_port") == "465"
        and (claws_bits.get("receive_server") or "").endswith("titan.email")
    )

# secret modes
def mode(p: Path):
    if not p.is_file():
        return None
    return oct(p.stat().st_mode & 0o777)

checks = []
def add(cid, ok, detail, severity="hard"):
    checks.append({"id": cid, "ok": bool(ok), "detail": detail, "severity": severity})

pub = int("$pub")
loc = int("$loc")
xdg = int("$xdg")
pkexec_n = int("$pkexec_n")

surf = (bgl.get("surfaces") or {})
add("public_listen_quiet", pub == 0, f"public={pub} local={loc}")
add("xdg_open_clear", xdg == 0, f"xdg-open count={xdg}")
add("no_pkexec_active", pkexec_n == 0, f"pkexec count={pkexec_n}", "soft")
add("bgl_secure_pin", bool(bgl.get("bgl")), f"bgl={bgl.get('bgl')} ts={bgl.get('ts')}")
add("inject_guard", True, f"flagged={inj.get('inject_flagged')} primary_cleared={inj.get('primary_cleared')} ts={inj.get('ts')}")
add("no_inject_pin", (out / "NO_INJECT").is_file(), "out/NO_INJECT present")
add("spv_av", bool(av), f"pids={av.get('pids')} fried={av.get('fried')} ts={av.get('ts')}")
add("heuristics", bool(est.get("heuristics")), f"gen={est.get('generation')} updated={est.get('updated')}")
if est.get("heuristics"):
    bad = [h["id"] for h in est["heuristics"] if h.get("pass") is False]
    add("heuristics_all_pass", not bad, "fail=" + ",".join(bad) if bad else "all pass")
add("claws_ssl_pins", claws_ok, json.dumps(claws_bits, separators=(",", ":")))
add("identity_present", bool(ident.get("address") or ident.get("user")),
    f"{ident.get('from_name','')} <{ident.get('address') or ident.get('user') or '?'}>")
tm = mode(pass_file)
add("titan_pass_mode", tm in (None, "0o600", "0o400") or (tm and int(tm, 8) in (0o600, 0o400)),
    f"titan.pass mode={tm or 'absent'} (absent ok if Claws store)", "soft")
xm = mode(xai_key)
add("xai_key_mode", xm in (None, "0o600", "0o400") or (xm and int(xm, 8) in (0o600, 0o400)),
    f"xai.key mode={xm or 'absent'}", "soft")
# world-writable secrets bad
for label, p in (("titan.pass", pass_file), ("xai.key", xai_key), ("identity.json", id_path)):
    if p.is_file():
        m = p.stat().st_mode & 0o077
        add(f"secret_no_group_other_{label}", m == 0, f"{p} other/group bits={oct(m)}", "hard" if m else "soft")

hard_fail = [c for c in checks if c["severity"] == "hard" and not c["ok"]]
soft_fail = [c for c in checks if c["severity"] == "soft" and not c["ok"]]
status = {
    "law": "BGS → BGF → BGL secure → SDF · SPV free · field hygiene AV · no polkit sudo",
    "ts": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
    "ok": len(hard_fail) == 0,
    "hard_fail": len(hard_fail),
    "soft_fail": len(soft_fail),
    "checks": checks,
    "live": {"public_listen": pub, "local_listen": loc, "xdg_open": xdg, "pkexec": pkexec_n},
    "email": {
        "address": ident.get("address") or claws_bits.get("address"),
        "user": ident.get("user") or claws_bits.get("user_id"),
        "from_name": ident.get("from_name"),
        "change": "mail-id set you@host",
    },
    "sources": {
        "bgl": str(out / "bgl_secure.json"),
        "inject": str(out / "av_inject_latest.json"),
        "spv_av": str(out / "spv_antivirus.json"),
        "heuristics": str(heu_path),
        "av": "Build/h7-av-close.sh · Build/spv-antivirus.sh · Grok on demand",
        "status": "Build/desk-security-status.sh",
    },
    "sudo": "mememe via SUDO_ASKPASS · never pkexec/polkit for desk AV",
}
(out / "desk_security_status.json").write_text(json.dumps(status, indent=2) + "\n")
lines = [
    "=== DESK SECURITY · AV FIELD ===",
    f"ts={status['ts']}",
    f"RESULT={'PASS' if status['ok'] else 'FAIL'} hard_fail={status['hard_fail']} soft_fail={status['soft_fail']}",
    f"email={status['email'].get('from_name')} <{status['email'].get('address')}> login={status['email'].get('user')}",
    f"live public={pub} local={loc} xdg={xdg} pkexec={pkexec_n}",
    "",
]
for c in checks:
    mark = "PASS" if c["ok"] else ("WARN" if c["severity"]=="soft" else "FAIL")
    lines.append(f"  [{mark}] {c['id']} · {c['detail']}")
lines += [
    "",
    "re-run AV:  bash Build/h7-av-close.sh once · bash Build/spv-antivirus.sh once",
    "status:     bash Build/desk-security-status.sh",
    "change email: mail-id set you@host",
    "law: remain IN · free never folds · no polkit for desk",
]
text = "\n".join(lines) + "\n"
(out / "DESK_SECURITY.txt").write_text(text)
print(text)
raise SystemExit(0 if status["ok"] else 1)
PY
