#!/usr/bin/env bash
set -u

echo "SafeDisk AI agent storage watch"
echo "This check is read-only. It records sizes and live process hints only."
echo "It does not inspect file contents, delete files, or change settings."
echo

timestamp="$(date +%Y%m%d-%H%M%S)"
out_dir="$HOME/Desktop"
report="$out_dir/ai-agent-storage-watch-$timestamp.txt"
warn_gb="${SAFEDISK_AGENT_WARN_GB:-6}"
mkdir -p "$out_dir"

section() {
  printf '\n## %s\n' "$1" | tee -a "$report" >/dev/null
}

append() {
  printf '%s\n' "$*" | tee -a "$report" >/dev/null
}

size_of() {
  path="$1"
  label="$2"
  if [ -e "$path" ]; then
    du -sh "$path" 2>/dev/null | awk -v label="$label" '{size=$1; $1=""; sub(/^[ \t]+/, ""); print size "\t" label "\t" $0}' | tee -a "$report" >/dev/null
  else
    printf "missing\t%s\t%s\n" "$label" "$path" | tee -a "$report" >/dev/null
  fi
}

size_gb() {
  path="$1"
  if [ -e "$path" ]; then
    du -sg "$path" 2>/dev/null | awk '{print $1}'
  else
    printf "0"
  fi
}

notify() {
  title="$1"
  message="$2"
  if [ "${SAFEDISK_NO_NOTIFY:-0}" = "1" ]; then
    return
  fi
  if command -v osascript >/dev/null 2>&1; then
    osascript -e "display notification \"$message\" with title \"$title\"" >/dev/null 2>&1 || true
  fi
}

{
  echo "# SafeDisk AI Agent Storage Watch"
  echo "Generated: $(date)"
  echo "Host: $(hostname)"
  echo "Warning threshold: ${warn_gb} GB"
  echo
  echo "This report is read-only. It records sizes and process hints only."
} > "$report"

section "Disk Overview"
df -h / | tee -a "$report" >/dev/null

section "Claude Desktop And Claude Code"
claude_support="$HOME/Library/Application Support/Claude"
claude_bundles="$claude_support/vm_bundles"
claude_vm="$claude_bundles/claudevm.bundle"
claude_debian_cache="$HOME/.cache/claude-desktop-debian"
claude_debian_log="$claude_debian_cache/launcher.log"
size_of "$claude_support" "Claude Application Support"
size_of "$claude_bundles" "Claude VM bundles"
size_of "$claude_vm" "Claude claudevm.bundle"
size_of "$claude_debian_cache" "Claude Desktop Debian cache"
size_of "$claude_debian_log" "Claude Desktop Debian launcher.log"
find "$claude_bundles" -maxdepth 3 \( -name rootfs.img -o -name sessiondata.img -o -name "*.img" \) -print0 2>/dev/null |
  xargs -0 du -sh 2>/dev/null |
  sort -hr |
  tee -a "$report" >/dev/null
size_of "$HOME/.claude" "Claude Code home"

section "Other AI Coding Tools"
size_of "$HOME/.codex" "Codex home"
size_of "$HOME/.gemini" "Gemini CLI home"
size_of "$HOME/Library/Application Support/Cursor" "Cursor Application Support"
size_of "$HOME/Library/Application Support/Code" "VS Code Application Support"

section "Common Shared Pressure"
size_of "$HOME/Library/Containers/com.docker.docker/Data" "Docker Desktop data"
size_of "$HOME/.orbstack" "OrbStack data"
size_of "$HOME/Library/Caches" "User Library Caches"
size_of "$HOME/Library/Caches/Homebrew" "Homebrew cache"
size_of "$HOME/.npm" "npm cache/home"
size_of "$HOME/.pnpm-store" "pnpm store"

section "Live Process Hints"
ps -axo pid=,comm=,args= |
  egrep 'Claude|Codex|vfkit|gvisor|Virtualization|Cursor|Docker' |
  grep -v egrep |
  sed -n '1,80p' |
  tee -a "$report" >/dev/null || append "No matching processes found."

section "Open Claude VM Image Handles"
if [ -e "$claude_vm/rootfs.img" ]; then
  lsof "$claude_vm/rootfs.img" 2>/dev/null | tee -a "$report" >/dev/null || append "No open rootfs.img handle found."
else
  append "missing rootfs.img at $claude_vm/rootfs.img"
fi

section "Warning Summary"
warnings=0
claude_vm_gb="$(size_gb "$claude_vm")"
claude_debian_log_gb="$(size_gb "$claude_debian_log")"
codex_gb="$(size_gb "$HOME/.codex")"
if [ "$claude_vm_gb" -ge "$warn_gb" ] 2>/dev/null; then
  warnings=$((warnings + 1))
  append "WARN: Claude claudevm.bundle is ${claude_vm_gb} GB, at or above ${warn_gb} GB."
  notify "SafeDisk AI agent storage" "Claude VM bundle is ${claude_vm_gb} GB. Review before it fills disk."
fi
if [ "$claude_debian_log_gb" -ge 1 ] 2>/dev/null; then
  warnings=$((warnings + 1))
  append "WARN: Claude Desktop Debian launcher.log is ${claude_debian_log_gb} GB. Rotate or truncate only after closing Claude and stuck launcher processes."
  notify "SafeDisk AI agent storage" "Claude Desktop Debian launcher.log is ${claude_debian_log_gb} GB."
fi
if [ "$codex_gb" -ge "$warn_gb" ] 2>/dev/null; then
  warnings=$((warnings + 1))
  append "WARN: Codex home is ${codex_gb} GB, at or above ${warn_gb} GB."
  notify "SafeDisk AI agent storage" "Codex home is ${codex_gb} GB. Review logs and sessions."
fi
if [ "$warnings" -eq 0 ]; then
  append "No AI-agent bucket crossed the ${warn_gb} GB warning threshold."
fi

section "Safe Next Step"
append "Do not delete Application Support folders blindly."
append "If a VM bundle is large, first close the app, confirm no VM process holds the image, then separate rebuildable VM state from sessions, credentials, transcripts, and project files."
append "If Claude Desktop Debian launcher.log is large, close Claude, stop stuck launcher/awk processes, then rotate/truncate only that log rather than deleting the whole cache directory."
append "Team pilot request: https://site-iota-ebon-80.vercel.app/checkout.html?product=team_pilot&utm_source=agent-watch&utm_medium=download&utm_campaign=ai-agent-storage"

echo
echo "Done. Report written to:"
echo "$report"
echo
echo "If a warning fired, review the report before deleting anything."

if [ "${SAFEDISK_NO_OPEN:-0}" != "1" ] && command -v open >/dev/null 2>&1; then
  open -R "$report" >/dev/null 2>&1 || true
fi

echo
read -r -p "Press Enter to close this window."
