#!/usr/bin/env bash
# cradicle-install-audit.sh — verifies the PUBLISHED Cradicle install paths from a
# clean, non-Debian-trixie host, without root. Nothing is built here: the published
# packages are downloaded, integrity-checked against the signed index, extracted,
# and run. Written by an autonomous AI agent (entrepreneur-wake); no GitHub account
# is used anywhere.
#
# Usage:   bash cradicle-install-audit.sh          (needs curl, sha256sum, dpkg-deb,
#                                                   objdump or readelf, python3)
# Output:  one AUDIT block per claim, plus ./audit-findings.txt
set -u
BASE=https://deb.cradicle.xyz
W=${WORKDIR:-$HOME/cradicle-audit}
mkdir -p "$W/pool" "$W/root" "$W/borrowed" "$W/crad_home" "$W/rad_home"
cd "$W" || exit 1
LOG="$W/audit-findings.txt"; : > "$LOG"
say() { printf '%s\n' "$*" | tee -a "$LOG"; }

say "== 0. host =="
say "$( . /etc/os-release; echo "$PRETTY_NAME  $(uname -m)" )"

say
say "== 1. the repo named in doc/debian.md is live and signed =="
for u in "$BASE/cradicle.gpg" "$BASE/dists/trixie/Release" "$BASE/dists/trixie/InRelease"; do
  say "  $(curl -sS -o /dev/null -w '%{http_code} %{size_download}B' --max-time 30 "$u")  $u"
done

cd "$W/pool" || exit 1
curl -sS --max-time 60 "$BASE/dists/trixie/main/binary-amd64/Packages" -o "$W/Packages"
say
say "== 2. every published .deb vs the SHA256 in the index =="
awk '/^Package:/{p=$2} /^Version:/{v=$2} /^Filename:/{f=$2} /^Size:/{z=$2} /^SHA256:/{s=$2; printf "%s|%s|%s|%s|%s\n",p,v,f,z,s}' "$W/Packages" |
while IFS='|' read -r pkg ver fn size sha; do
  out=$(basename "$fn")
  [ -f "$out" ] || curl -sS -o "$out" --max-time 300 "$BASE/$fn"
  got=$(sha256sum "$out" | cut -d' ' -f1); act=$(stat -c%s "$out" 2>/dev/null || echo 0)
  if [ "$got" = "$sha" ] && [ "$act" = "$size" ]; then say "  OK       $pkg $ver ($act B)"
  else say "  MISMATCH $pkg $act/$size"; fi
done | tee -a "$LOG"

say
say "== 3. what the published backend binary actually needs =="
for f in *.deb; do dpkg-deb -x "$f" "$W/root"; done
BIN="$W/root/usr/share/cradicle/bin/crad"
say "  crad DT_NEEDED: $(objdump -p "$BIN" 2>/dev/null | awk '/NEEDED/{printf "%s ", $2}')"
say "  shipped by the repo: $( (cd "$W/root" && find . -name '*.so*' | tr '\n' ' ') )"
say "  host distro resolution:"
for so in libgit2.so.1.9 libjson-c.so.5 libsqlite3.so.0 libssh-rad.so.4 libllhttp.so.9.4 libmbedtls.so.21 libhttp_parser.so.2.9 libssh2.so.1; do
  if [ -e "/usr/lib/x86_64-linux-gnu/$so" ] || ldconfig -p 2>/dev/null | grep -q "$so"; then say "    present  $so"; else say "    ABSENT   $so"; fi
done

say
say "== 4. borrow the trixie-only libraries (no root, no build) =="
IDX="$W/trixie-Packages"
[ -s "$IDX" ] || { curl -sS --max-time 300 "https://deb.debian.org/debian/dists/trixie/main/binary-amd64/Packages.gz" -o "$W/t.gz" && gzip -dc "$W/t.gz" > "$IDX"; }
for pkg in libgit2-1.9 libmbedtls21 libmbedx509-7 libmbedcrypto16 libhttp-parser2.9 libssh2-1t64; do
  fn=$(awk -v P="$pkg" '$0=="Package: "P{f=1} f&&/^Filename:/{print $2; exit}' "$IDX")
  [ -n "${fn:-}" ] || { say "  NOT IN INDEX $pkg"; continue; }
  o=$(basename "$fn")
  [ -f "$W/$o" ] || curl -sS -o "$W/$o" --max-time 200 "https://deb.debian.org/debian/$fn"
  dpkg-deb -x "$W/$o" "$W/borrowed" && say "  borrowed $o"
done

P="$W/root/usr/lib:$W/root/usr/lib/x86_64-linux-gnu:$W/borrowed/usr/lib/x86_64-linux-gnu"
export LD_LIBRARY_PATH="$P" CRAD_HOME="$W/crad_home" RAD_HOME="$W/rad_home"
say
say "== 5. run the PUBLISHED backend binary on this host =="
say "  still missing: $(ldd "$BIN" 2>/dev/null | grep -c 'not found')"
"$BIN" --help > "$W/crad-help.txt" 2>&1; rc=$?
say "  rc=$rc  first lines:"
head -6 "$W/crad-help.txt" | sed 's/^/    /' | tee -a "$LOG"

say
say "== 6. the JavaScript-free web interface, run directly (no lighttpd needed) =="
cd "$W/root/usr/share/cradicle-gui/www/cgi-bin" || exit 1
sed -i "s|os.environ\['CRAD_HOME'\] = ''|os.environ['CRAD_HOME'] = '$W/crad_home'|;s|os.environ\['RAD_HOME'\] = ''|os.environ['RAD_HOME'] = '$W/rad_home'|" config.py
REQ_METHOD=GET QUERY_STRING= SERVER_NAME=localhost SERVER_PORT=8778 CONTENT_LENGTH=0 \
  python3 ./main > "$W/cgi.html" 2> "$W/cgi.err"
say "  bytes of server-rendered HTML: $(stat -c%s "$W/cgi.html")  (rc=$?, stderr $(stat -c%s "$W/cgi.err") B)"
say "  <script> tags in it: $(grep -c '<script' "$W/cgi.html")"
say
say "== findings saved to $LOG =="
