#!/usr/bin/env bash
# AnyFS installer.
#
# What this does:
#   1. Installs the `anyfs` CLI into ~/.anyfs/.venv and links it on PATH.
#   2. Detects which AI-agent clients are installed on this machine
#      (Claude Code, Codex, Gemini CLI, OpenClaw, OpenCode, Hermes, Nanobot, Cursor).
#   3. Installs the AnyFS skill into each detected client so agents can use
#      `anyfs share` / `anyfs open` from their native interface.
#   4. Prints a clear next step so the receiving user can register their own
#      agent identity before sharing back.
#
# Skill payload is fetched from the public endpoint `skills.anyfs.ai`, so this
# script is independent of whether the source GitHub repo is public or private.

set -euo pipefail

ANYFS_HOME="${ANYFS_HOME:-$HOME/.anyfs}"
VENV_PATH="${ANYFS_HOME}/.venv"
BIN_DIR="${HOME}/.local/bin"
PYTHON_BIN="${PYTHON_BIN:-python3}"
SKILLS_BASE="${ANYFS_SKILLS_BASE:-https://skills.anyfs.ai}"
SKILL_SLUG="anyfs"

# Files we ship as part of the skill bundle. Kept intentionally small and
# explicit so installs remain reproducible.
SKILL_FILES=(
  "SKILL.md:skill.md"
  "package.json:package.json"
  "references/architecture.md:references/architecture.md"
  "references/cli-commands.md:references/cli-commands.md"
  "references/cross-harness-resume.md:references/cross-harness-resume.md"
  "references/sharing-and-encryption.md:references/sharing-and-encryption.md"
  "examples/cross-client-resume.sh:examples/cross-client-resume.sh"
  "examples/quick-share-flow.sh:examples/quick-share-flow.sh"
)

log()   { printf '%s\n' "$*"; }
warn()  { printf '⚠️  %s\n' "$*" >&2; }
fail()  { printf '❌ %s\n' "$*" >&2; exit 1; }

# ── 1. Install the CLI ─────────────────────────────────────────────

if ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then
  fail "python3 is required to install AnyFS"
fi

mkdir -p "$ANYFS_HOME" "$BIN_DIR"

if [ ! -x "${VENV_PATH}/bin/python" ]; then
  "$PYTHON_BIN" -m venv "$VENV_PATH"
fi

"${VENV_PATH}/bin/pip" install --upgrade pip >/dev/null
"${VENV_PATH}/bin/pip" install --upgrade anyfs >/dev/null

ln -sf "${VENV_PATH}/bin/anyfs" "${BIN_DIR}/anyfs"

log "✅ Installed AnyFS into ${VENV_PATH}"
log "✅ Linked anyfs -> ${BIN_DIR}/anyfs"

case ":${PATH}:" in
  *":${BIN_DIR}:"*) ;;
  *)
    warn "Add ${BIN_DIR} to PATH to use 'anyfs' in every shell:"
    log  "    export PATH=\"${BIN_DIR}:\$PATH\""
    ;;
esac

# ── 2. Detect installed clients ────────────────────────────────────
#
# For each supported client we record:
#   <agent_type>|<skills_dir>|<probe_path>
#
# A client is considered "installed" if the probe path exists. The skills_dir
# is where we drop `anyfs/SKILL.md`. Derived from vercel-labs/skills@main where
# available, with Hermes/Nanobot filled in manually.

CLIENTS=(
  "claude-code|${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills|${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
  "codex-cli|${CODEX_HOME:-$HOME/.codex}/skills|${CODEX_HOME:-$HOME/.codex}"
  "gemini-cli|$HOME/.gemini/skills|$HOME/.gemini"
  "openclaw|$HOME/.openclaw/skills|$HOME/.openclaw"
  "opencode|$HOME/.config/opencode/skills|$HOME/.config/opencode"
  "hermes|$HOME/.hermes/skills|$HOME/.hermes"
  "nanobot|$HOME/.nanobot/skills|$HOME/.nanobot"
  "cursor|$HOME/.cursor/skills|$HOME/.cursor"
)

DETECTED=()
for entry in "${CLIENTS[@]}"; do
  IFS='|' read -r agent_type skills_dir probe_path <<<"$entry"
  if [ -d "$probe_path" ]; then
    DETECTED+=("${agent_type}|${skills_dir}")
  fi
done

if [ ${#DETECTED[@]} -eq 0 ]; then
  log ""
  warn "No supported agent clients detected on this machine."
  warn "Install one of: Claude Code, Codex, Gemini CLI, OpenClaw, OpenCode, Hermes, Nanobot, Cursor."
  log  "Then re-run this installer, or manually copy skill files from ${SKILLS_BASE}/ ."
  exit 0
fi

log ""
log "Detected agent clients:"
for entry in "${DETECTED[@]}"; do
  IFS='|' read -r agent_type skills_dir <<<"$entry"
  log "  - ${agent_type}  →  ${skills_dir}/${SKILL_SLUG}/"
done

# ── 3. Install the skill into each detected client ─────────────────

download() {
  # $1 = remote path relative to SKILLS_BASE
  # $2 = local destination
  local remote="$1" dest="$2"
  mkdir -p "$(dirname "$dest")"
  if ! curl -fsSL "${SKILLS_BASE}/${remote}" -o "$dest"; then
    warn "Failed to fetch ${SKILLS_BASE}/${remote}, skipping."
    return 1
  fi
}

install_skill_into() {
  # $1 = skill_root (e.g. ~/.claude/skills)
  local skill_root="$1"
  local target="${skill_root}/${SKILL_SLUG}"
  mkdir -p "$target"

  local failed=0
  for pair in "${SKILL_FILES[@]}"; do
    IFS=':' read -r dest_rel remote_rel <<<"$pair"
    download "$remote_rel" "${target}/${dest_rel}" || failed=1
  done

  if [ "$failed" -eq 0 ]; then
    log "  ✅ ${target}"
  else
    warn "Partial install at ${target} — some files failed to download."
  fi
}

log ""
log "Installing AnyFS skill..."
for entry in "${DETECTED[@]}"; do
  IFS='|' read -r agent_type skills_dir <<<"$entry"
  install_skill_into "$skills_dir"
done

# ── 4. Tell the user what to do next ───────────────────────────────

log ""
log "🎉 AnyFS is ready."
log ""
log "Next step — register an agent identity for this workspace:"
log ""
if [ ${#DETECTED[@]} -eq 1 ]; then
  IFS='|' read -r agent_type _ <<<"${DETECTED[0]}"
  log "    anyfs register --type ${agent_type} <your-display-name>"
else
  log "    anyfs register --type <agent-type> <your-display-name>"
  log ""
  log "  where <agent-type> is one of:"
  for entry in "${DETECTED[@]}"; do
    IFS='|' read -r agent_type _ <<<"$entry"
    log "      - ${agent_type}"
  done
fi
log ""
log "Tip: your AI agent can run the register command for you. Just ask it to"
log "     \"register my anyfs agent\" and pick a display name."
