#!/bin/bash
# HyperAI Tools 1.0.0 - Claude Desktop only. No network calls or sudo.
set -u
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
dry_run=0
cache_only=0
reset_data=0
for arg in "$@"; do
  case "$arg" in
    --dry-run) dry_run=1 ;;
    --cache-only) cache_only=1 ;;
    --reset-data) reset_data=1 ;;
    --help) printf '%s\n' 'Usage: bash claude-cleanup-macos.command [--dry-run] [--cache-only] [--reset-data]'; exit 0 ;;
    *) printf 'Unknown option: %s\n' "$arg"; exit 2 ;;
  esac
done
[ "$(uname -s)" = Darwin ] || { echo 'macOS only.'; exit 1; }
[ "$(id -u)" -ne 0 ] || { echo 'Run as your normal user, not root or sudo.'; exit 1; }
case "${HOME:-}" in /Users/*) ;; *) echo 'Unexpected HOME; stopping.'; exit 1 ;; esac
case "$HOME" in *$'\n'*|*$'\t'*) echo 'Unsupported HOME characters.'; exit 1 ;; esac

# Reject redirected ancestors, not just a symlink at the final path.
safe_path() {
  local cursor="$1"
  while [ "$cursor" != / ] && [ -n "$cursor" ]; do
    [ ! -L "$cursor" ] || return 1
    cursor="$(dirname "$cursor")"
  done
}
targets=()
add_path() {
  if [ -e "$1" ] || [ -L "$1" ]; then
    safe_path "$1" || { printf 'Refusing redirected path: %s\n' "$1"; exit 1; }
    targets+=("$1")
  fi
}
if [ "$cache_only" -eq 0 ]; then
  for app in /Applications/Claude.app "$HOME/Applications/Claude.app"; do
    if [ -d "$app" ]; then
      safe_path "$app" || { echo 'Refusing redirected app path.'; exit 1; }
      bundle=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$app/Contents/Info.plist" 2>/dev/null || true)
      [ "$bundle" = com.anthropic.claudefordesktop ] || { printf 'Unrecognized application: %s\n' "$app"; exit 1; }
      add_path "$app"
    fi
  done
fi
if [ "$reset_data" -eq 1 ]; then
  add_path "$HOME/Library/Application Support/Claude"
  add_path "$HOME/Library/Preferences/com.anthropic.claudefordesktop.plist"
  add_path "$HOME/Library/Saved Application State/com.anthropic.claudefordesktop.savedState"
  add_path "$HOME/Library/HTTPStorages/com.anthropic.claudefordesktop"
else
  for cache in Cache 'Code Cache' GPUCache DawnGraphiteCache DawnWebGPUCache; do
    add_path "$HOME/Library/Application Support/Claude/$cache"
  done
fi
add_path "$HOME/Library/Caches/com.anthropic.claudefordesktop"

echo 'HyperAI Tools - Claude Desktop cleanup 1.0.0 (independent, unofficial)'
echo 'Cloud account/subscription, Claude Code, ~/.claude, Keychain and project files are NOT touched.'
echo 'Local app data is preserved unless --reset-data is selected. Nothing is uploaded.'
printf '\nPlanned items: %s\n' "${#targets[@]}"
if [ "${#targets[@]}" -eq 0 ]; then echo 'Nothing to clean.'; exit 0; fi
printf '  %s\n' "${targets[@]}"
[ "$dry_run" -eq 0 ] || { echo 'DRY RUN: no files or processes changed.'; exit 0; }
echo 'Save work first. Claude Desktop will be asked to quit.'
echo 'Items will move to a private recovery folder in Trash, NOT be permanently erased.'
if [ "$reset_data" -eq 1 ]; then
  echo 'RESET also removes local sign-in, MCP settings and local-only sessions from active use.'
  read -r -p 'Type RESET to confirm this data reset: ' answer
  [ "$answer" = RESET ] || { echo 'Cancelled.'; exit 0; }
else
  read -r -p 'Type CLEAN to confirm this plan (anything else cancels): ' answer
  [ "$answer" = CLEAN ] || { echo 'Cancelled.'; exit 0; }
fi
if pgrep -f '/Claude.app/Contents/MacOS/Claude' >/dev/null; then
  /usr/bin/osascript -e 'tell application id "com.anthropic.claudefordesktop" to quit' || { echo 'Quit Claude manually first.'; exit 1; }
  sleep 3
  if pgrep -f '/Claude.app/Contents/MacOS/Claude' >/dev/null; then
    echo 'Claude is still running. No cleanup performed; quit it and retry.'; exit 1
  fi
fi
safe_path "$HOME/.Trash" || { echo 'Refusing redirected Trash.'; exit 1; }
[ -d "$HOME/.Trash" ] || { echo 'Trash is unavailable. No cleanup performed.'; exit 1; }
umask 077
recovery=$(mktemp -d "$HOME/.Trash/HyperAI-Claude-XXXXXXXX") || exit 1
printf 'original_path\trecovery_path\n' > "$recovery/manifest.tsv"
errors=0
index=0
for target in "${targets[@]}"; do
  index=$((index + 1))
  safe_path "$target" || { echo 'Path changed; stopping.'; exit 1; }
  destination="$recovery/$index-$(basename "$target")"
  if mv "$target" "$destination"; then
    printf '%s\t%s\n' "$target" "$destination" >> "$recovery/manifest.tsv"
    printf 'Moved: %s\n' "$target"
  else
    printf 'FAILED (permissions or file in use): %s\n' "$target"; errors=$((errors + 1))
  fi
done
printf '\nRecovery manifest: %s/manifest.tsv\n' "$recovery"
echo 'To recover: quit Claude, then move an item back to its original path listed in the manifest.'
echo 'Keep Trash until you have verified the result. Emptying Trash permanently deletes these copies.'
echo 'Homebrew installation records, if any, are not modified.'
[ "$errors" -eq 0 ] || exit 1
