#!/usr/bin/env bash
# H7 AUTORESEARCH · love whole internet as field · research dirt + allowlisted probes
#
# NOT free-roam thrash. Two lanes:
#   LOCAL  · iron sensors (secure-learn, field-clear, scars, public, thrash ps)
#   CONTAINED · SPV curl allowlist only (health of beloved field nodes)
#
#   ./Build/h7-autoresearch.sh once|local|probe|status
#
# Law: BGS→BGF→BGL→SDF · SPV free · love net · clear dirt · never ML · God Bless
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
OUT="$ROOT/out"
JSON="$OUT/h7_autoresearch.json"
FEED="$OUT/h7_vocab_feed.tsv"
ALLOW="$ROOT/Build/spv-curl-allow.list"
CONTAIN="$ROOT/Build/spv-curl-contain.sh"
cmd="${1:-once}"
TS="$(date -Iseconds)"

n0() { local v="${1//[^0-9]/}"; echo "${v:-0}"; }
jget() {
  local f="$1" k="$2"
  [[ -f "$f" ]] || { echo ""; return; }
  python3 - "$f" "$k" <<'PY' 2>/dev/null || true
import json,sys
try:
  d=json.load(open(sys.argv[1]))
  v=d
  for p in sys.argv[2].split("."):
    v=v.get(p) if isinstance(v,dict) else None
  print("" if v is None else v)
except Exception:
  print("")
PY
}
say() { echo "[$TS] AUTORESEARCH · $*"; }

research_local() {
  local findings=()
  local pub scars inject dirt sec_ok newc outside grok thrash_ps forever mega vocab

  pub=$(ss -ltnH 2>/dev/null | awk '$4 !~ /^127\.|^\[::1\]|%lo/ {c++} END{print c+0}')
  scars=$(n0 "$(jget "$OUT/scar_check_latest.json" scar_count)")
  inject=$(n0 "$(jget "$OUT/av_inject_latest.json" inject_flagged)")
  dirt=$(n0 "$(jget "$OUT/h7_field_clear.json" dirt_score)")
  sec_ok=$(jget "$OUT/h7_secure_learn.json" ok)
  newc=$(n0 "$(jget "$OUT/h7_secure_learn.json" learned.new_comm_classes)")
  outside=$(n0 "$(jget "$OUT/h7_secure_learn.json" inside_out.outside_heuristics)")
  grok=$(n0 "$(jget "$OUT/h7_secure_learn.json" learned.grok_family_pids)")
  thrash_ps=$(ps -eo comm= 2>/dev/null | awk '/^krtx-spv$|^cover$/ {c++} END{print c+0}')
  forever=false
  if [[ -f "$OUT/h7_forever.pid" ]] && kill -0 "$(cat "$OUT/h7_forever.pid")" 2>/dev/null; then forever=true; fi
  mega=$(n0 "$(wc -l <"$OUT/h7fast/mega.tsv" 2>/dev/null | tr -d ' ')")
  vocab=$(n0 "$(wc -l <"$OUT/h7_vocab_self.tsv" 2>/dev/null | tr -d ' ')")

  (( pub > 0 )) && findings+=("ALERT_public_listen=$pub")
  (( scars > 0 )) && findings+=("scar=$scars")
  (( inject > 0 )) && findings+=("inject_flagged")
  (( dirt >= 3 )) && findings+=("dirt_high=$dirt")
  (( newc > 5 )) && findings+=("new_comm_classes=$newc")
  (( outside > 5 )) && findings+=("outside_h=$outside")
  [[ "$sec_ok" == "False" || "$sec_ok" == "false" ]] && findings+=("secure_not_ok")
  (( thrash_ps > 2 )) && findings+=("thrash_ps=$thrash_ps")
  [[ "$forever" == "true" ]] && findings+=("forever_on") || findings+=("forever_off")
  findings+=("mega_$mega" "vocab_$vocab" "grok_$grok" "dirt_$dirt")

  # top NEW_COMM / OUTSIDE from heuristics (quality intel)
  local heur_bits=()
  if [[ -f "$OUT/h7_secure_heuristics.tsv" ]]; then
    while IFS=$'\t' read -r _ts kind side name rest; do
      [[ -z "$kind" ]] && continue
      case "$kind" in
        NEW_COMM|PUBLIC_LISTEN|NEW_SERVICE|FILE_NEW)
          heur_bits+=("${kind}:${name:0:28}")
          ;;
      esac
      (( ${#heur_bits[@]} >= 8 )) && break
    done < <(tail -40 "$OUT/h7_secure_heuristics.tsv" 2>/dev/null || true)
  fi

  LOCAL_PUB=$pub LOCAL_SCARS=$scars LOCAL_INJECT=$inject LOCAL_DIRT=$dirt
  LOCAL_SEC=$sec_ok LOCAL_NEWC=$newc LOCAL_OUT=$outside LOCAL_GROK=$grok
  LOCAL_THRASH=$thrash_ps LOCAL_FOREVER=$forever LOCAL_MEGA=$mega LOCAL_VOCAB=$vocab
  LOCAL_FINDINGS="${findings[*]}"
  LOCAL_HEUR="${heur_bits[*]:-none}"
}

# contained probe · only allowlisted hosts · never free thrash crawl
research_probe() {
  PROBE_OK=0 PROBE_FAIL=0 PROBE_BITS=()
  local hosts=(127.0.0.1:18772)
  # optional beloved field host from allowlist
  if grep -qx 'biggrinrtx.com' "$ALLOW" 2>/dev/null; then
    hosts+=(biggrinrtx.com)
  fi
  local h code
  for h in "${hosts[@]}"; do
    if [[ "$h" == *:* && "$h" != *://* ]]; then
      # local desk API
      code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 2 "http://$h/h7" 2>/dev/null || echo 000)
    else
      # contained if unit present, else short direct allowlist hit
      if [[ -x "$CONTAIN" ]]; then
        code=$(timeout 8 bash "$CONTAIN" curl -sS -o /dev/null -w '%{http_code}' --max-time 5 "https://$h/" 2>/dev/null | tail -1 || echo 000)
      else
        code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 5 "https://$h/" 2>/dev/null || echo 000)
      fi
    fi
    code=$(n0 "$code")
    if (( code >= 200 && code < 500 )); then
      PROBE_OK=$((PROBE_OK + 1))
      PROBE_BITS+=("ok:$h:$code")
    else
      PROBE_FAIL=$((PROBE_FAIL + 1))
      PROBE_BITS+=("fail:$h:$code")
    fi
  done
}

write_json() {
  local lane="$1"
  # sanitize arrays to JSON-ish strings
  local findings_js heur_js probe_js
  findings_js=$(printf '%s' "${LOCAL_FINDINGS:-}" | sed 's/"/\\"/g')
  heur_js=$(printf '%s' "${LOCAL_HEUR:-}" | sed 's/"/\\"/g')
  probe_js=$(printf '%s' "${PROBE_BITS[*]:-}" | sed 's/"/\\"/g')
  cat >"$JSON" <<EOF
{
  "ts": "$TS",
  "word": "H7_AUTORESEARCH",
  "she": "Hostess 7",
  "lane": "$lane",
  "philosophy": {
    "love_whole_internet": true,
    "research_is_not_thrash": true,
    "local_first": true,
    "contained_allowlist_only": true,
    "line": "autoresearch local iron + SPV-contained probes · love field · clear dirt · never free-roam thrash"
  },
  "local": {
    "public_listen": ${LOCAL_PUB:-0},
    "scar_count": ${LOCAL_SCARS:-0},
    "inject_flagged": ${LOCAL_INJECT:-0},
    "dirt_score": ${LOCAL_DIRT:-0},
    "secure_ok": "${LOCAL_SEC:-}",
    "new_comm": ${LOCAL_NEWC:-0},
    "outside_h": ${LOCAL_OUT:-0},
    "grok_pids": ${LOCAL_GROK:-0},
    "thrash_ps": ${LOCAL_THRASH:-0},
    "forever_on": ${LOCAL_FOREVER:-false},
    "mega_N": ${LOCAL_MEGA:-0},
    "vocab_N": ${LOCAL_VOCAB:-0},
    "findings": "$findings_js",
    "heuristics_tail": "$heur_js"
  },
  "probe": {
    "ok": ${PROBE_OK:-0},
    "fail": ${PROBE_FAIL:-0},
    "bits": "$probe_js"
  },
  "ok": true,
  "stack": "bash+asm",
  "law": "love whole net · research dirt · SPV contain · God Bless"
}
EOF
}

feed_scroll() {
  {
    printf '%s\t%s\t%s\t%s\n' "$TS" "autoresearch" "FIELD" "research"
    # push a few findings into ticker fuel
    local f
    for f in ${LOCAL_FINDINGS:-}; do
      printf '%s\t%s\t%s\t%s\n' "$TS" "$f" "RESEARCH" "scroll"
    done | head -6
  } >>"$FEED" 2>/dev/null || true
}

run_local() {
  research_local
  PROBE_OK=0 PROBE_FAIL=0 PROBE_BITS=()
  write_json local
  feed_scroll
  say "local dirt=${LOCAL_DIRT:-0} pub=${LOCAL_PUB:-0} findings=${LOCAL_FINDINGS:-none}"
  cat "$JSON"
}

run_once() {
  research_local
  research_probe
  write_json once
  feed_scroll
  say "once dirt=${LOCAL_DIRT:-0} probe_ok=${PROBE_OK:-0} fail=${PROBE_FAIL:-0}"
  cat "$JSON"
}

status() {
  if [[ -f "$JSON" ]]; then cat "$JSON"; else say "no research yet · run once|local"; fi
}

case "$cmd" in
  local) run_local ;;
  once|probe) run_once ;;
  status) status ;;
  *)
    echo "usage: $0 once|local|probe|status" >&2
    echo "  local iron first · SPV-contained allowlist probes · never free thrash crawl" >&2
    exit 2
    ;;
esac
