#!/usr/bin/env bash
# SECURE MEDIA · camera + audio · field hygiene (not commercial AV)
# Law: BGS → BGF → BGL secure · SPV free · never fold
# Allow: obs (stream) · pipewire · wireplumber · pulse · known desk
# Fry: unknown holders of /dev/video* capture · unknown pcm*c capture
# NO pkill -f · exact PID · sudo non-interactive only
set -u
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
OUT="$ROOT/out"
mkdir -p "$OUT"
export SUDO_PASS="${SUDO_PASS:-mememe}"
export SUDO_ASKPASS="${SUDO_ASKPASS:-$ROOT/Build/sudo-askpass.sh}"
LOG="$OUT/secure-media-$(date +%Y%m%d-%H%M%S).txt"
TS=$(date -Iseconds)

say() { echo "$*" | tee -a "$LOG"; }

# allowlist comms that may hold camera/mic
allow_comm() {
  case "$1" in
    obs|pipewire|wireplumber|pipewire-pulse|pulseaudio|chrome|chromium|firefox|waterfox|\
    zoom|Discord|slack|krtx-engine|krtx-spv|grok|Xorg)
      return 0 ;;
  esac
  return 1
}

fried=0
flagged=0
cam_holders=0
aud_holders=0
cam_unknown=0
aud_unknown=0

say "############################################"
say "# SECURE MEDIA · camera + audio · $TS"
say "############################################"

# --- CAMERA / V4L ---
say "=== CAMERA · /dev/video* /dev/media* ==="
{
  echo "ts=$TS"
  echo "devices:"
  ls -la /dev/video* /dev/media* 2>/dev/null || echo "  (none)"
  echo "holders:"
} >"$OUT/secure_camera.txt"

for dev in /dev/video* /dev/media*; do
  [[ -e "$dev" ]] || continue
  # fuser PIDs
  pids=$(fuser "$dev" 2>/dev/null | tr ' ' '\n' | sed '/^$/d' || true)
  for pid in $pids; do
    [[ -d /proc/$pid ]] || continue
    cam_holders=$((cam_holders + 1))
    comm=$(cat /proc/$pid/comm 2>/dev/null || echo '?')
    args=$(tr '\0' ' ' </proc/$pid/cmdline 2>/dev/null | cut -c1-120)
    if allow_comm "$comm"; then
      line="KEEP pid=$pid comm=$comm dev=$dev"
      say "$line"
      echo "$line · $args" >>"$OUT/secure_camera.txt"
    else
      cam_unknown=$((cam_unknown + 1))
      flagged=$((flagged + 1))
      line="UNKNOWN_CAM pid=$pid comm=$comm dev=$dev"
      say "$line"
      echo "$line · $args" >>"$OUT/secure_camera.txt"
      # fry unknown camera grabbers (not allowlisted)
      if [[ "$comm" != "fuser" && "$comm" != "bash" && "$comm" != "sudo" ]]; then
        # long agent wrappers skip
        (( ${#args} > 200 )) && continue
        kill -TERM "$pid" 2>/dev/null || true
        kill -KILL "$pid" 2>/dev/null && { fried=$((fried+1)); say "FRY cam $pid $comm"; } || true
      fi
    fi
  done
done

# v4l names if available
if command -v v4l2-ctl >/dev/null 2>&1; then
  v4l2-ctl --list-devices 2>/dev/null | tee -a "$OUT/secure_camera.txt" | head -30 | while read -r l; do say "v4l $l"; done || true
fi

# --- AUDIO / capture PCM ---
say "=== AUDIO · /dev/snd capture + control ==="
{
  echo "ts=$TS"
  echo "cards:"
  cat /proc/asound/cards 2>/dev/null || true
  echo "holders:"
} >"$OUT/secure_audio.txt"

# capture devices pcm*c and control
for dev in /dev/snd/pcm*c /dev/snd/controlC* /dev/snd/seq; do
  [[ -e "$dev" ]] || continue
  pids=$(fuser "$dev" 2>/dev/null | tr ' ' '\n' | sed '/^$/d' || true)
  for pid in $pids; do
    [[ -d /proc/$pid ]] || continue
    aud_holders=$((aud_holders + 1))
    comm=$(cat /proc/$pid/comm 2>/dev/null || echo '?')
    args=$(tr '\0' ' ' </proc/$pid/cmdline 2>/dev/null | cut -c1-120)
    # classify
    if allow_comm "$comm"; then
      line="KEEP pid=$pid comm=$comm dev=$dev"
      say "$line"
      echo "$line · $args" >>"$OUT/secure_audio.txt"
    else
      # capture path (pcm*c) unknown is harder
      case "$dev" in
        */pcm*c)
          aud_unknown=$((aud_unknown + 1))
          flagged=$((flagged + 1))
          line="UNKNOWN_MIC pid=$pid comm=$comm dev=$dev"
          say "$line"
          echo "$line · $args" >>"$OUT/secure_audio.txt"
          (( ${#args} > 200 )) && continue
          if [[ "$comm" != "fuser" && "$comm" != "bash" ]]; then
            kill -TERM "$pid" 2>/dev/null || true
            kill -KILL "$pid" 2>/dev/null && { fried=$((fried+1)); say "FRY mic $pid $comm"; } || true
          fi
          ;;
        *)
          line="NOTE pid=$pid comm=$comm dev=$dev"
          echo "$line · $args" >>"$OUT/secure_audio.txt"
          ;;
      esac
    fi
  done
done

# arecord/parec lurkers by comm
for d in /proc/[0-9]*; do
  pid=${d#/proc/}
  [[ -r "$d/comm" ]] || continue
  c=$(cat "$d/comm" 2>/dev/null || true)
  case "$c" in
    arecord|parec|pw-record|ffmpeg|gst-launch*)
      args=$(tr '\0' ' ' <"$d/cmdline" 2>/dev/null | cut -c1-160)
      # if holding video or pcm capture without obs parent context — flag
      if allow_comm "$c"; then
        :
      else
        # ffmpeg used by obs sometimes — check ppid comm
        pp=$(awk '/^PPid:/{print $2}' "$d/status" 2>/dev/null || echo 0)
        pc=$(cat /proc/$pp/comm 2>/dev/null || echo)
        if [[ "$pc" == "obs" ]]; then
          say "KEEP $c pid=$pid under obs"
          continue
        fi
        # only fry pure arecord/parec grabbers
        case "$c" in
          arecord|parec|pw-record)
            say "FRY lurker recorder $c pid=$pid"
            kill -TERM "$pid" 2>/dev/null || true
            kill -KILL "$pid" 2>/dev/null && fried=$((fried+1)) || true
            flagged=$((flagged+1))
            ;;
          *)
            say "FLAG recorder-class $c pid=$pid (not auto-fry)"
            flagged=$((flagged+1))
            ;;
        esac
      fi
      ;;
  esac
done

# --- perms surface: devices stay root:video / root:audio (report only) ---
say "=== PERMS · device nodes ==="
ls -la /dev/video0 /dev/video1 /dev/snd/pcmC1D0c 2>/dev/null | tee -a "$LOG" || true

# --- mark ---
cam_clean=$(( cam_unknown == 0 ? 1 : 0 ))
aud_clean=$(( aud_unknown == 0 ? 1 : 0 ))
bgl_media=$(( cam_clean & aud_clean ))

cat >"$OUT/secure_media.json" <<JSON
{
  "ts": "$TS",
  "surface": "camera+audio",
  "av": "field hygiene media secure · not commercial",
  "camera": {
    "holders": $cam_holders,
    "unknown": $cam_unknown,
    "clean": $cam_clean,
    "devices": ["/dev/video0", "/dev/video1", "/dev/media0"],
    "allow": ["obs", "pipewire", "wireplumber", "browsers"]
  },
  "audio": {
    "holders": $aud_holders,
    "unknown_capture": $aud_unknown,
    "clean": $aud_clean,
    "allow": ["obs", "pipewire", "wireplumber", "pulse"]
  },
  "fried": $fried,
  "flagged": $flagged,
  "bgl_media": $bgl_media,
  "log": "$LOG",
  "law": "BGL secure · keep stream · fry unknown cam/mic grabbers"
}
JSON
cp -f "$OUT/secure_media.json" "$OUT/secure_media_latest.json"
echo "MEDIA $(date -Iseconds) cam_clean=$cam_clean aud_clean=$aud_clean fried=$fried flagged=$flagged bgl_media=$bgl_media" >"$OUT/SECURE_MEDIA"

say "=== RESULT ==="
say "cam_holders=$cam_holders unknown=$cam_unknown clean=$cam_clean"
say "aud_holders=$aud_holders unknown_cap=$aud_unknown clean=$aud_clean"
say "fried=$fried flagged=$flagged bgl_media=$bgl_media"
say "SECURE MEDIA DONE · remain IN"
echo "$LOG"
