#!/bin/bash
# install.sh — Install Forge globally, ready to run
#
# Usage:
#   ./install.sh                                                # from npm
#   ./install.sh local                                          # from local source
#   ./install.sh --enterprise-key=fortinet:github_pat_xxx           # + persist one enterprise key
#   ./install.sh --enterprise-key=fortinet:pat --enterprise-key=…   # multiple keys
#
# Enterprise keys are encrypted with AES-256-GCM and stored in
# `<dataDir>/.enterprise-keys.json` — see Phase 1 of
# forge-enterprise-improvements design doc for the marketplace model.

set -e

# Collect enterprise keys + leave non-key args in $@ for downstream parsing.
ENTERPRISE_KEY_ARGS=()
NEW_ARGS=()
for arg in "$@"; do
  case "$arg" in
    --enterprise-key=*) ENTERPRISE_KEY_ARGS+=("$arg") ;;
    *) NEW_ARGS+=("$arg") ;;
  esac
done
set -- "${NEW_ARGS[@]:-}"

# tmux is required for browser terminals — warn early if missing
if ! command -v tmux >/dev/null 2>&1; then
  echo "[forge] ⚠️  tmux not found — Forge terminals won't work without it."
  case "$(uname -s)" in
    Darwin)
      echo "[forge] Install: brew install tmux"
      if command -v brew >/dev/null 2>&1; then
        read -r -p "[forge] Run 'brew install tmux' now? [y/N] " reply
        case "$reply" in [yY]*) brew install tmux ;; esac
      fi
      ;;
    Linux)
      if command -v apt-get >/dev/null 2>&1; then
        echo "[forge] Install: sudo apt install -y tmux"
      elif command -v dnf >/dev/null 2>&1; then
        echo "[forge] Install: sudo dnf install -y tmux"
      elif command -v pacman >/dev/null 2>&1; then
        echo "[forge] Install: sudo pacman -S tmux"
      else
        echo "[forge] Install tmux via your distro's package manager."
      fi
      ;;
    *)
      echo "[forge] See https://github.com/tmux/tmux/wiki/Installing"
      ;;
  esac
  echo ""
fi

# Agent CLI check — at least one of claude / codex / aider is needed
if ! command -v claude >/dev/null 2>&1 \
   && ! command -v codex >/dev/null 2>&1 \
   && ! command -v aider >/dev/null 2>&1; then
  echo "[forge] ⚠️  No agent CLI found (claude / codex / aider)."
  echo "[forge] Install Claude Code:  npm install -g @anthropic-ai/claude-code"
  echo "[forge] Install Codex:        https://github.com/openai/codex#installation"
  echo "[forge] Or configure API-only profiles in Settings after login."
  echo ""
fi

# Optional helpers used by built-in workflows. Warn-only — Forge installs
# fine without them, but specific pipelines will fail at the shell step
# if they're missing (e.g. mr-review-fix calls glab + jq).
missing_opts=()
command -v jq   >/dev/null 2>&1 || missing_opts+=("jq")
command -v glab >/dev/null 2>&1 || missing_opts+=("glab")
if [ ${#missing_opts[@]} -gt 0 ]; then
  echo "[forge] ⚠️  Optional CLIs missing: ${missing_opts[*]}"
  echo "[forge]    jq   — needed by shell pipelines that parse JSON"
  echo "[forge]    glab — needed by the mr-review-fix workflow (GitLab API)"
  case "$(uname -s)" in
    Darwin)
      echo "[forge] Install: brew install ${missing_opts[*]}"
      if command -v brew >/dev/null 2>&1; then
        read -r -p "[forge] Install now? [y/N] " reply
        case "$reply" in [yY]*) brew install "${missing_opts[@]}" ;; esac
      fi
      ;;
    Linux)
      echo "[forge] Install via your distro's package manager."
      case " ${missing_opts[*]} " in
        *" glab "*) echo "[forge]    glab — see https://gitlab.com/gitlab-org/cli#installation" ;;
      esac
      ;;
  esac
  echo ""
fi

if [ "$1" = "local" ] || [ "$1" = "--local" ]; then
  # Build a real npm tarball from the current working tree and install it
  # globally exactly the way `npm install -g @aion0/forge` would after a
  # publish. This runs the `prepack` hook (bundles cli/mw.mjs), respects
  # .npmignore, and uses npm (not pnpm) for the global install — so the
  # behaviour matches what a real user gets from `forge upgrade`.
  echo "[forge] Building from local source (npm pack flow)..."
  SRC_DIR="$(pwd)"
  # Wipe Turbopack's incremental cache + previous .next bundle.
  # Without this, Next.js 16 sometimes reuses stale chunks for files
  # whose source hash didn't shift enough between builds (observed
  # silently shipping old tool-dispatcher logic). Cheap insurance.
  echo "[forge] Clearing .next + Turbopack cache for a clean build..."
  rm -rf "$SRC_DIR/.next" "$SRC_DIR/node_modules/.cache" 2>/dev/null || true
  echo "[forge] Running pnpm build..."
  pnpm build || echo "[forge] Build completed with warnings (non-critical)"
  echo "[forge] Packing tarball..."
  PACK_DIR="$(mktemp -d -t forge-pack-XXXXXX)"
  TARBALL="$(cd "$PACK_DIR" && npm pack "$SRC_DIR" --silent)"
  TARBALL_PATH="$PACK_DIR/$TARBALL"
  echo "[forge] Built $TARBALL_PATH"
  echo "[forge] Uninstalling previous global install..."
  npm uninstall -g @aion0/forge 2>/dev/null || true
  echo "[forge] Installing tarball globally..."
  (cd /tmp && npm install -g "$TARBALL_PATH")
  rm -rf "$PACK_DIR"
else
  echo "[forge] Installing from npm..."
  rm -rf "$(npm root -g)/@aion0/forge" 2>/dev/null || true
  npm cache clean --force 2>/dev/null || true
  # Install from /tmp to avoid pnpm node_modules conflict
  (cd /tmp && npm install -g @aion0/forge)
  echo "[forge] Building..."
  cd "$(npm root -g)/@aion0/forge" && (npx next build || echo "[forge] Build completed with warnings") && cd -
fi

echo ""

# Persist any enterprise keys collected from CLI args (encrypted on disk;
# server doesn't need to be running for this).
if [ ${#ENTERPRISE_KEY_ARGS[@]} -gt 0 ]; then
  echo "[forge] Registering ${#ENTERPRISE_KEY_ARGS[@]} enterprise key(s)..."
  forge --add-enterprise-key "${ENTERPRISE_KEY_ARGS[@]}" || \
    echo "[forge] ⚠️  Enterprise-key registration failed — you can retry later via Settings → Marketplace Providers."
  echo ""
fi

echo "[forge] Done."
forge --version
echo "Run: forge server start"
