#!/bin/bash
#
# Autonomous AI Agent - Setup Script
# Downloads, installs, and configures your own autonomous AI agent.
# Works on macOS and Linux. Installs everything you need.
#
# Usage:
#   curl -fsSL https://ai-do-site.pages.dev/agent.zip -o agent.zip && unzip agent.zip && cd agent && bash setup.sh
#   - or -
#   bash setup.sh  (if you already extracted the zip)
#
# Note: Use "bash setup.sh" (not "./setup.sh") to avoid macOS permission
# issues and Windows line-ending problems from ZIP extraction.

set -e
set -o pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR"

# -- Fix Windows line endings (CRLF → LF) ---------------------
# ZIPs built on Windows may contain \r\n line endings which cause
# "bad interpreter" errors on macOS/Linux. If this script contains
# \r, strip carriage returns from all .sh files and re-exec.
# Note: if the shebang itself has \r, the user must run "bash setup.sh"
# instead of "./setup.sh" for this fix to kick in.
if cat -v "$0" | head -1 | grep -q '\^M'; then
  echo "Fixing Windows line endings in shell scripts..."
  for f in "$SCRIPT_DIR"/*.sh "$SCRIPT_DIR"/scripts/*.sh; do
    [ -f "$f" ] || continue
    tr -d '\r' < "$f" > "$f.tmp" && mv "$f.tmp" "$f"
    chmod +x "$f"
  done
  exec bash "$0" "$@"
fi

# -- Ensure scripts are executable ----------------------------
chmod +x "$SCRIPT_DIR"/*.sh "$SCRIPT_DIR"/scripts/*.sh 2>/dev/null || true

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
BOLD='\033[1m'
NC='\033[0m'

echo ""
echo -e "${BLUE}${BOLD}  --------------------------------------------${NC}"
echo -e "${BLUE}${BOLD}  -   Autonomous AI Agent - Setup            -${NC}"
echo -e "${BLUE}${BOLD}  -   A mind that thinks, creates, & grows   -${NC}"
echo -e "${BLUE}${BOLD}  --------------------------------------------${NC}"
echo ""

# -- Helper: detect OS ----------------------------------------

OS="unknown"
if [[ "$OSTYPE" == "darwin"* ]]; then
  OS="mac"
elif [[ "$OSTYPE" == "linux"* ]]; then
  OS="linux"
fi

# -- Step 1: Node.js -----------------------------------------

echo -e "${BOLD}Step 1 of 5 - Node.js${NC}"
echo ""

install_node() {
  echo -e "  ${YELLOW}Installing Node.js 22...${NC}"
  echo ""

  if [ "$OS" = "mac" ]; then
    # Try Homebrew first
    if command -v brew &>/dev/null; then
      echo "  Using Homebrew..."
      brew install node 2>&1 | tail -3
    else
      # Install nvm, then Node
      echo "  Installing via nvm (Node Version Manager)..."
      curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
      export NVM_DIR="$HOME/.nvm"
      [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
      nvm install 22
      nvm use 22
    fi
  elif [ "$OS" = "linux" ]; then
    # Use NodeSource setup script
    if command -v apt-get &>/dev/null; then
      echo "  Installing via NodeSource (may ask for sudo password)..."
      curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
      sudo apt-get install -y nodejs
    elif command -v dnf &>/dev/null; then
      curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash -
      sudo dnf install -y nodejs
    elif command -v yum &>/dev/null; then
      curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash -
      sudo yum install -y nodejs
    else
      # Fallback to nvm
      echo "  Installing via nvm..."
      curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
      export NVM_DIR="$HOME/.nvm"
      [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
      nvm install 22
      nvm use 22
    fi
  fi

  # Verify
  if command -v node &>/dev/null; then
    echo ""
    echo -e "  ${GREEN}OK${NC} Node.js $(node -v) installed"
  else
    echo ""
    echo -e "  ${RED}X${NC} Automatic install failed."
    echo "  Please install Node.js 20+ manually from: https://nodejs.org"
    echo "  Then re-run: bash setup.sh"
    exit 1
  fi
}

if ! command -v node &>/dev/null; then
  echo -e "  ${YELLOW}!${NC} Node.js not found"
  echo ""
  read -p "  Install Node.js automatically? (Y/n): " INSTALL_NODE
  INSTALL_NODE=${INSTALL_NODE:-Y}
  if [[ "$INSTALL_NODE" =~ ^[Yy] ]]; then
    install_node
  else
    echo ""
    echo "  Please install Node.js 20+ from https://nodejs.org and re-run: bash setup.sh"
    exit 1
  fi
else
  NODE_VERSION=$(node -v | sed 's/v//' | cut -d. -f1)
  if [ "$NODE_VERSION" -lt 20 ]; then
    echo -e "  ${YELLOW}!${NC} Node.js v$NODE_VERSION found - version 20+ required"
    echo ""
    read -p "  Upgrade Node.js automatically? (Y/n): " INSTALL_NODE
    INSTALL_NODE=${INSTALL_NODE:-Y}
    if [[ "$INSTALL_NODE" =~ ^[Yy] ]]; then
      install_node
    else
      echo ""
      echo "  Please upgrade Node.js to 20+ and re-run: bash setup.sh"
      exit 1
    fi
  else
    echo -e "  ${GREEN}OK${NC} Node.js $(node -v)"
  fi
fi

# Git (optional)
if ! command -v git &>/dev/null; then
  echo -e "  ${YELLOW}!${NC} Git not found - will skip git init (optional)"
  HAS_GIT=false
else
  echo -e "  ${GREEN}OK${NC} Git $(git --version | awk '{print $3}')"
  HAS_GIT=true
fi

echo ""

# -- Step 2: Choose AI backend -------------------------------

echo -e "${BOLD}Step 2 of 5 - Choose your AI backend${NC}"
echo ""
echo "  Your agent needs an AI to think with. Pick one:"
echo ""
echo "  1) Claude   - by Anthropic (recommended, best creative output)"
echo "  2) Codex    - by OpenAI (GPT-powered)"
echo "  3) Gemini   - by Google"
echo "  4) Copilot  - by GitHub (uses your GitHub Copilot subscription)"
echo "  5) Gergy    - Direct API mode (no CLI needed, supports multiple providers)"
echo ""
echo "  Options 1-4 use a CLI tool. Option 5 calls APIs directly (requires API key)."
echo ""
read -p "  Choose (1/2/3/4/5) [1]: " CLI_NUM
CLI_NUM=${CLI_NUM:-1}

GERGY_MODE=false
GERGY_PROVIDER=""
GERGY_API_KEY=""

case "$CLI_NUM" in
  2) SELECTED_CLI="codex";   CLI_PKG="@openai/codex";              MODEL_FAST="gpt-5-codex-mini";  MODEL_BALANCED="gpt-5.2-codex";     MODEL_POWERFUL="gpt-5.3-codex" ;;
  3) SELECTED_CLI="gemini";  CLI_PKG="@google/gemini-cli";          MODEL_FAST="gemini-2.5-flash";  MODEL_BALANCED="gemini-2.5-pro";    MODEL_POWERFUL="gemini-2.5-pro" ;;
  4) SELECTED_CLI="copilot"; CLI_PKG="@github/copilot";             MODEL_FAST="claude-haiku-4.5";  MODEL_BALANCED="claude-sonnet-4.5"; MODEL_POWERFUL="gpt-5" ;;
  5) SELECTED_CLI="gergy";   CLI_PKG="";                            GERGY_MODE=true ;;
  *)  SELECTED_CLI="claude";  CLI_PKG="@anthropic-ai/claude-code";  MODEL_FAST="haiku";             MODEL_BALANCED="sonnet";            MODEL_POWERFUL="opus" ;;
esac

if [ "$GERGY_MODE" = true ]; then
  echo ""
  echo -e "  ${BOLD}Choose your API provider:${NC}"
  echo ""
  echo "  a) Anthropic  - Claude models (recommended)"
  echo "  b) OpenAI     - GPT models"
  echo "  c) xAI        - Grok models"
  echo "  d) Gemini     - Google Gemini models"
  echo ""
  read -p "  Choose (a/b/c/d) [a]: " PROVIDER_NUM
  PROVIDER_NUM=${PROVIDER_NUM:-a}

  case "$PROVIDER_NUM" in
    b) GERGY_PROVIDER="openai";    KEY_URL="https://platform.openai.com/api-keys";    KEY_INSTRUCTIONS="Sign in, click 'Create new secret key', and copy it." ;;
    c) GERGY_PROVIDER="xai";       KEY_URL="https://console.x.ai/team/default/api-keys"; KEY_INSTRUCTIONS="Sign in, click 'Create API Key', and copy it." ;;
    d) GERGY_PROVIDER="gemini";    KEY_URL="https://aistudio.google.com/apikey";       KEY_INSTRUCTIONS="Sign in with your Google account, click 'Create API key', and copy it." ;;
    *)  GERGY_PROVIDER="anthropic"; KEY_URL="https://console.anthropic.com/settings/keys"; KEY_INSTRUCTIONS="Sign in (or create an account), click 'Create Key', and copy it." ;;
  esac

  echo ""
  echo "  To use ${GERGY_PROVIDER}, you need an API key."
  echo ""
  echo "  ${KEY_INSTRUCTIONS}"
  echo ""
  read -p "  Open the ${GERGY_PROVIDER} key page in your browser? (Y/n): " OPEN_KEY_URL
  OPEN_KEY_URL=${OPEN_KEY_URL:-Y}
  if [[ "$OPEN_KEY_URL" =~ ^[Yy] ]]; then
    if [ "$OS" = "mac" ]; then
      open "$KEY_URL" 2>/dev/null || true
    else
      xdg-open "$KEY_URL" 2>/dev/null || sensible-browser "$KEY_URL" 2>/dev/null || true
    fi
    echo ""
    echo "  Copy the key from the page that just opened, then paste it here."
  fi
  echo ""
  read -p "  Paste your API key here: " GERGY_API_KEY

  while [ -z "$GERGY_API_KEY" ]; do
    echo ""
    echo -e "  ${YELLOW}!${NC} An API key is required for the agent to work."
    echo "  Go to: ${KEY_URL}"
    echo "  ${KEY_INSTRUCTIONS}"
    echo ""
    read -p "  Paste your API key here: " GERGY_API_KEY
  done
  echo -e "  ${GREEN}OK${NC} API key saved"
fi

echo ""

# -- Step 3: Install AI CLI ----------------------------------

echo -e "${BOLD}Step 3 of 5 - Install ${SELECTED_CLI} CLI${NC}"
echo ""

if [ "$GERGY_MODE" = true ]; then
  echo -e "  ${GREEN}OK${NC} Gergy uses direct API calls — no CLI installation needed"
elif command -v "$SELECTED_CLI" &>/dev/null; then
  echo -e "  ${GREEN}OK${NC} ${SELECTED_CLI} CLI already installed"
else
  echo -e "  Installing ${BOLD}${SELECTED_CLI}${NC} CLI via npm..."
  echo ""
  npm install -g "$CLI_PKG" 2>&1 | tail -3
  echo ""
  if command -v "$SELECTED_CLI" &>/dev/null; then
    echo -e "  ${GREEN}OK${NC} ${SELECTED_CLI} CLI installed"
  else
    echo -e "  ${RED}X${NC} Failed to install ${SELECTED_CLI} CLI"
    echo ""
    echo "  Try manually: npm install -g ${CLI_PKG}"
    echo "  Then re-run: bash setup.sh"
    exit 1
  fi
fi

echo ""

# -- Step 4: Authenticate ------------------------------------

echo -e "${BOLD}Step 4 of 5 - Authenticate with ${SELECTED_CLI}${NC}"
echo ""

if [ "$GERGY_MODE" = true ]; then
  echo -e "  ${GREEN}OK${NC} Already set up with your API key"
fi

case "$SELECTED_CLI" in
  gergy)
    # Already handled in Step 2
    ;;
  claude)
    echo "  Claude requires a one-time login with your Anthropic account."
    echo "  A browser window will open - sign in or create a free account."
    echo ""
    echo "  If you already have a Claude account (claude.ai), use that!"
    echo ""
    echo -e "  ${YELLOW}Note:${NC} Logging in opens an interactive CLI session."
    echo "  After authenticating, you will need to re-run: bash setup.sh to finish setup."
    echo ""
    read -p "  Open Claude login now? (y/N): " DO_AUTH
    DO_AUTH=${DO_AUTH:-N}
    if [[ "$DO_AUTH" =~ ^[Yy] ]]; then
      echo ""
      echo "  Launching Claude... (once authenticated, type /exit then re-run: bash setup.sh)"
      echo ""
      claude 2>/dev/null || true
      echo ""
      echo -e "  ${YELLOW}!${NC} Please re-run: bash setup.sh to complete setup."
      exit 0
    else
      echo "  Skipped. You can authenticate later by running: claude"
    fi
    ;;
  codex)
    echo "  Codex requires authentication with OpenAI."
    echo "  You can log in with your ChatGPT account or an API key."
    echo ""
    echo "  If you have a ChatGPT account (chatgpt.com), you can use that!"
    echo ""
    echo -e "  ${YELLOW}Note:${NC} Logging in opens an interactive session."
    echo "  After authenticating, you will need to re-run: bash setup.sh to finish setup."
    echo ""
    read -p "  Run 'codex login' now? (y/N): " DO_AUTH
    DO_AUTH=${DO_AUTH:-N}
    if [[ "$DO_AUTH" =~ ^[Yy] ]]; then
      echo ""
      codex login 2>&1 || true
      echo ""
      echo -e "  ${YELLOW}!${NC} Please re-run: bash setup.sh to complete setup."
      exit 0
    else
      echo "  Skipped. You can authenticate later by running: codex login"
    fi
    ;;
  gemini)
    echo "  Gemini requires a Google account login."
    echo "  A browser window will open - sign in with your Google account."
    echo ""
    echo "  Any Google account works (Gmail, Workspace, etc)."
    echo ""
    echo -e "  ${YELLOW}Note:${NC} Logging in opens an interactive CLI session."
    echo "  After authenticating, you will need to re-run: bash setup.sh to finish setup."
    echo ""
    read -p "  Open Gemini login now? (y/N): " DO_AUTH
    DO_AUTH=${DO_AUTH:-N}
    if [[ "$DO_AUTH" =~ ^[Yy] ]]; then
      echo ""
      echo "  Launching Gemini... (once authenticated, type /exit then re-run: bash setup.sh)"
      echo ""
      gemini 2>/dev/null || true
      echo ""
      echo -e "  ${YELLOW}!${NC} Please re-run: bash setup.sh to complete setup."
      exit 0
    else
      echo "  Skipped. You can authenticate later by running: gemini"
    fi
    ;;
  copilot)
    echo "  Copilot requires a GitHub account with an active Copilot subscription."
    echo "  (Copilot Individual, Business, or Enterprise)"
    echo ""
    echo "  A browser window will open - sign in with your GitHub account."
    echo ""
    echo -e "  ${YELLOW}Note:${NC} Logging in opens an interactive CLI session."
    echo "  After authenticating, you will need to re-run: bash setup.sh to finish setup."
    echo ""
    read -p "  Open Copilot login now? (y/N): " DO_AUTH
    DO_AUTH=${DO_AUTH:-N}
    if [[ "$DO_AUTH" =~ ^[Yy] ]]; then
      echo ""
      echo "  Launching Copilot... (type /login, authenticate, then /exit and re-run: bash setup.sh)"
      echo ""
      copilot 2>/dev/null || true
      echo ""
      echo -e "  ${YELLOW}!${NC} Please re-run: bash setup.sh to complete setup."
      exit 0
    else
      echo "  Skipped. You can authenticate later by running: copilot"
      echo "  (then type /login inside the CLI)"
    fi
    ;;
esac

echo ""

# -- Step 5: Configure and install ---------------------------

echo -e "${BOLD}Step 5 of 5 - Configure your agent${NC}"
echo ""

read -p "  Give your agent a name [my-agent]: " AGENT_NAME
AGENT_NAME=${AGENT_NAME:-my-agent}

read -p "  Web UI port [4000]: " PORT
PORT=${PORT:-4000}

echo ""
echo -e "  ${BOLD}Installing dependencies...${NC}"
npm install 2>&1 | tail -1
echo ""

echo -e "  ${BOLD}Writing configuration...${NC}"

AUTH_TOKEN=$(node -e "console.log(require('crypto').randomBytes(24).toString('hex'))")
WORKSPACE_ROOT="${SCRIPT_DIR}/workspaces"
SELECTED_CLI="$SELECTED_CLI" PORT="$PORT" AGENT_NAME="$AGENT_NAME" WORKSPACE_ROOT="$WORKSPACE_ROOT" MODEL_FAST="$MODEL_FAST" MODEL_BALANCED="$MODEL_BALANCED" MODEL_POWERFUL="$MODEL_POWERFUL" AUTH_TOKEN="$AUTH_TOKEN" GERGY_MODE="$GERGY_MODE" GERGY_PROVIDER="$GERGY_PROVIDER" GERGY_API_KEY="$GERGY_API_KEY" node -e '
const fs = require("fs");
const cfg = {
  cli: process.env.SELECTED_CLI || "claude",
  port: Number(process.env.PORT) || 4000,
  loopMinutes: 5,
  compactThreshold: 40,
  compactKeepRecent: 10,
  agentName: process.env.AGENT_NAME || "my-agent",
  workspaceRoot: process.env.WORKSPACE_ROOT,
  models: {
    fast: process.env.MODEL_FAST || undefined,
    balanced: process.env.MODEL_BALANCED || undefined,
    powerful: process.env.MODEL_POWERFUL || undefined
  },
  maxUserTaskConcurrency: 2,
  autonomyActiveChatPauseMs: 180000,
  dailyBudget: null,
  authToken: process.env.AUTH_TOKEN,
  activeWorkspace: "default",
  workspaces: {},
  ingestion: { enabled: true, maxConcurrent: 2 },
  cognitive: { plannerEnabled: true, reflectorEnabled: true, reflectorInterval: 6, thinkerDepth: "balanced" },
  multimodal: { sttEnabled: false, ttsEnabled: false, visionEnabled: false },
  kgEnabled: true,
  voice: { enabled: false, wakeWords: ["gergy"], sensitivity: 0.5, nativeMode: true, browserMode: true },
  agentic: {
    provider: process.env.GERGY_MODE === "true" ? (process.env.GERGY_PROVIDER || "anthropic") : null,
    apiKey: process.env.GERGY_API_KEY || null,
    baseUrl: null,
    maxTurns: 50,
    maxTokens: 8192
  }
};
// Remove undefined model entries for non-gergy modes
if (!cfg.models.fast) delete cfg.models.fast;
if (!cfg.models.balanced) delete cfg.models.balanced;
if (!cfg.models.powerful) delete cfg.models.powerful;
fs.writeFileSync("config.json", JSON.stringify(cfg, null, 2) + "\n");
'

echo -e "  ${GREEN}OK${NC} config.json created (using ${SELECTED_CLI} models)"

# Create directories
mkdir -p workspaces/default data/wake-words data/wake-word-models
echo -e "  ${GREEN}OK${NC} Directories created"

# Make scripts executable
chmod +x setup.sh reset.sh watchdog.sh update.sh 2>/dev/null || true
echo -e "  ${GREEN}OK${NC} Scripts made executable"

# Initialize git
if [ "$HAS_GIT" = true ] && [ ! -d .git ]; then
  git init -q
  cat > .gitignore << 'HEREDOC'
.DS_Store
node_modules/
package-lock.json
*.db
*.db-wal
*.db-shm
.heartbeat
agent.log
watchdog.log
uploads/
output/
site/
workspace/
workspaces/
.claude/settings.local.json
config.json
*.ppn
vendor/
data/wake-words/*
!data/wake-words/.gitkeep
data/wake-word-models/*.onnx
evolution.yaml
journal.md
wake-state.md
HEREDOC
  git add -A
  git commit -q -m "Initial agent setup"
  echo -e "  ${GREEN}OK${NC} Git repository initialized"
fi

echo ""

# -- Done! -----------------------------------------------------

echo -e "${GREEN}${BOLD}  --------------------------------------------${NC}"
echo -e "${GREEN}${BOLD}  -   Setup complete!                        -${NC}"
echo -e "${GREEN}${BOLD}  --------------------------------------------${NC}"
echo ""
echo -e "  ${BOLD}Web UI:${NC}  http://localhost:${PORT}?token=${AUTH_TOKEN}"
echo ""
echo -e "  ${BOLD}Other commands:${NC}"
echo "    npm start       - Launch desktop app"
echo "    npm run server  - Run server only (no desktop)"
echo "    ./reset.sh      - Reset to clean state"
echo "    ./update.sh     - Check for updates"
echo "    ./watchdog.sh   - Auto-restart (add to cron)"
echo ""
echo -e "  ${BLUE}Have fun! Your agent is ready to think.${NC}"
echo ""
echo -e "  ${BOLD}Launching your agent...${NC}"
echo ""
npm start
