#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
LOG="$HOME/cli-install-wsl.log"
REPORT="$HOME/cli-install-report.md"
BACKUP_DIR="$HOME/cli-install-backups-wsl-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
exec > >(tee -a "$LOG") 2>&1

echo "=== CLI install script (interactive) ==="
echo "Log: $LOG"
echo

# Helpers
prompt_yesno() {
  local msg="$1"
  local ans
  while true; do
    read -rp "$msg [y/n]: " ans
    case "$ans" in
      [Yy]*) return 0 ;;
      [Nn]*) return 1 ;;
      *) echo "Please answer y or n." ;;
    esac
  done
}

preview_url() {
  local url="$1"
  echo
  echo "Previewing first 200 lines of $url"
  echo "---- BEGIN PREVIEW ----"
  curl -fsSL "$url" 2>/dev/null | sed -n '1,200p'
  echo "---- END PREVIEW ----"
  echo
}

safe_run_pipe_installer() {
  # $1 = url, $2 = shell (bash|sh)
  local url="$1"; local shellcmd="${2:-bash}"
  echo "About to run installer from: $url"
  if ! prompt_yesno "Have you reviewed the preview and want to execute it now?"; then
    echo "Skipping $url"
    return 1
  fi
  # Execute installer (interactive; sudo prompts will show)
  curl -fsSL "$url" | $shellcmd
}

# 0) WSL check
if grep -qi microsoft /proc/version 2>/dev/null || grep -qi microsoft /proc/sys/kernel/osrelease 2>/dev/null; then
  echo "Running inside WSL (or WSL2). Proceeding."
else
  echo "Warning: This script is intended for WSL/Ubuntu. Continue only if you know what you are doing."
  if ! prompt_yesno "Continue anyway?"; then
    echo "Aborting."
    exit 1
  fi
fi

# 1) Detect environment
echo "== Environment =="
uname -a
if command -v lsb_release >/dev/null 2>&1; then lsb_release -a || true; else cat /etc/os-release || true; fi
echo "Shell: $SHELL"
echo "User: $USER"
echo "Home: $HOME"
echo "PATH: $PATH"
echo "Arch: $(uname -m)"
echo

# 2) Back up shell configs
echo "Backing up shell configs to $BACKUP_DIR"
for f in "$HOME/.bashrc" "$HOME/.profile" "$HOME/.zshrc"; do
  if [ -f "$f" ]; then
    cp -a "$f" "$BACKUP_DIR/$(basename "$f").bak" || true
    echo "Backed up $f"
  else
    echo "No file: $f"
  fi
done
echo

# 3) Install prerequisites
if prompt_yesno "Install apt prerequisites (curl ca-certificates git unzip gnupg lsb-release build-essential)?"; then
  sudo apt-get update
  sudo apt-get install -y curl ca-certificates git unzip gnupg lsb-release build-essential apt-transport-https
else
  echo "Skipping prerequisites install. Ensure required tools exist."
fi
echo

# 4) Node check and optional install (Node 20 recommended)
NEED_NODE_INSTALL=0
if command -v node >/dev/null 2>&1; then
  NV="$(node -v 2>/dev/null || true)"
  echo "Found node: $NV"
  MAJ="$(echo "$NV" | sed -E 's/v([0-9]+).*/\1/')" || MAJ=0
  if [ -z "$MAJ" ] || [ "$MAJ" -lt 18 ]; then
    NEED_NODE_INSTALL=1
    echo "Node major version $MAJ is older than 18; Node 20 is recommended."
  fi
else
  NEED_NODE_INSTALL=1
  echo "Node not found."
fi

if [ "$NEED_NODE_INSTALL" -eq 1 ]; then
  if prompt_yesno "Install Node 20 via NodeSource (recommended) now?"; then
    curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
    sudo apt-get install -y nodejs
  else
    echo "Skipping Node install. Codex npm installer may require Node >=18."
  fi
fi
echo "Node version: $(node -v 2>/dev/null || echo 'none')"
echo "npm version: $(npm -v 2>/dev/null || echo 'none')"
echo

# 5) Ensure npm global prefix writable (user-level)
CUR_PREFIX="$(npm config get prefix 2>/dev/null || echo '')"
echo "Current npm prefix: $CUR_PREFIX"
if [ -z "$CUR_PREFIX" ] || [ ! -w "$CUR_PREFIX" ] || [ "$CUR_PREFIX" = "/usr" ]; then
  echo "Configuring user npm global prefix at ~/.npm-global"
  mkdir -p "$HOME/.npm-global"
  npm config set prefix "$HOME/.npm-global"
  if ! grep -q '\.npm-global' "$HOME/.profile" 2>/dev/null; then
    printf '\n# npm global bin\nexport PATH="$HOME/.npm-global/bin:$HOME/.local/bin:$PATH"\n' >> "$HOME/.profile"
    echo "Appended npm PATH to ~/.profile"
  fi
  export PATH="$HOME/.npm-global/bin:$HOME/.local/bin:$PATH"
fi
echo "Effective PATH now contains: $HOME/.npm-global/bin (if present)"
echo

# 6) Claude Code CLI (official)
CLAUDE_URL="https://claude.ai/install.sh"
echo "Claude Code installer (official): $CLAUDE_URL"
preview_url "$CLAUDE_URL"
if prompt_yesno "Install Claude Code CLI now?"; then
  safe_run_pipe_installer "$CLAUDE_URL" bash || echo "Claude installer failed or was skipped."
else
  echo "Skipped Claude install."
fi
echo

# 7) OpenAI Codex CLI (official)
echo "OpenAI Codex CLI preferred method: npm i -g @openai/codex"
if prompt_yesno "Attempt npm global install @openai/codex now?"; then
  if npm i -g @openai/codex --no-progress; then
    echo "Codex npm install succeeded."
  else
    echo "npm global install failed. You can choose to run the official installer fallback."
    if prompt_yesno "Attempt official fallback installer (curl https://chatgpt.com/codex/install.sh | sh)?"; then
      preview_url "https://chatgpt.com/codex/install.sh"
      safe_run_pipe_installer "https://chatgpt.com/codex/install.sh" sh || echo "Codex fallback failed or skipped."
    fi
  fi
else
  echo "Skipped Codex npm install."
fi
echo

# 8) Devin CLI (official)
DEVIN_URL="https://cli.devin.ai/install.sh"
echo "Devin CLI official installer: $DEVIN_URL"
preview_url "$DEVIN_URL"
if prompt_yesno "Install Devin CLI now?"; then
  safe_run_pipe_installer "$DEVIN_URL" bash || echo "Devin installer failed or was skipped."
else
  echo "Skipped Devin install."
fi
echo

# 9) Antigravity (agy) — manual only
ANTIGRAVITY_PAGE="https://antigravity.google/product/antigravity-cli"
echo "Antigravity CLI official docs page: $ANTIGRAVITY_PAGE"
echo "This script will not auto-run installers from Antigravity. Review the official page and follow their instructions."
if prompt_yesno "Fetch and preview the Antigravity docs page snippet?"; then
  echo "Previewing page snippet (first 300 lines):"
  curl -fsSL "$ANTIGRAVITY_PAGE" | sed -n '1,300p' || echo "Failed to fetch Antigravity page."
  echo
  echo "If the page specifies an official installer URL you trust, run it manually (example placeholder):"
  echo "  curl -fsSL <official-agy-install-url> | bash"
fi
echo

# 10) Reload profile and PATH
echo "Reloading ~/.profile (if present) to pick PATH changes"
if [ -f "$HOME/.profile" ]; then
  # shellcheck disable=SC1090
  source "$HOME/.profile" || true
fi
export PATH="$HOME/.npm-global/bin:$HOME/.local/bin:$PATH"
echo "PATH now: $PATH"
echo

# 11) Verification
echo "=== Verification ==="
declare -A RESULTS
for cmd in claude codex agy devin; do
  echo "---- $cmd ----"
  if command -v "$cmd" >/dev/null 2>&1; then
    p="$(command -v "$cmd")"
    out="$($cmd --version 2>&1 || $cmd --help 2>&1 || echo 'no-version-output')"
    echo "Found: $p"
    echo "Output: $out"
    RESULTS["$cmd"]="installed|$out|$p"
  else
    echo "Not found in PATH."
    RESULTS["$cmd"]="not-installed||"
  fi
  echo
done

# Also verify in a clean non-login shell
echo "=== Clean shell checks ==="
bash -lc 'command -v claude && claude --version 2>&1 || echo "claude: not-found"'
bash -lc 'command -v codex && codex --version 2>&1 || echo "codex: not-found"'
bash -lc 'command -v devin && (devin --version 2>&1 || devin --help 2>&1) || echo "devin: not-found"'
bash -lc 'command -v agy && agy --version 2>&1 || echo "agy: not-found"'

# 12) Create report
echo "Writing report to $REPORT"
cat > "$REPORT" <<EOF
# CLI install report (WSL)
Generated: $(date)
OS: $(lsb_release -d -s 2>/dev/null || grep PRETTY_NAME /etc/os-release | cut -d= -f2-)
User: $USER
Home: $HOME

Install summary:
EOF

for key in claude codex devin agy; do
  val="${RESULTS[$key]:-not-installed||}"
  IFS='|' read -r inst ver path <<< "$val"
  if [ "$inst" = "installed" ] || [ "$inst" = "installed_npm" ] || [ "$inst" = "installed_fallback" ]; then
    status="yes"
  elif [ "$inst" = "not-installed" ]; then
    status="no"
  else
    status="$inst"
  fi
  {
    echo
    echo "## $key"
    echo "Installed?: $status"
    echo "Path: ${path:-}"
    echo "Version/Output: ${ver:-}"
  } >> "$REPORT"
done

cat >> "$REPORT" <<EOF

Antigravity (agy): Manual verification required. Official page: $ANTIGRAVITY_PAGE

PATH changes:
- If npm prefix was adjusted, ~/.npm-global/bin was added to ~/.profile

Notes:
- No auth performed by this script. Use each CLI's documented login command (do not put API keys in shell profiles).
- Backups saved to: $BACKUP_DIR
Log file: $LOG
EOF

echo
echo "DONE. Report: $REPORT"
echo "Tail of log:"
tail -n 50 "$LOG" || true
echo
echo "If any install failed, paste the log or report and I will help debug."

# End of script
