#!/usr/bin/env bash
#
# ragex-mcp -- Start Ragex as an MCP server in stdio mode.
#
# Designed for editors that communicate with MCP servers over stdin/stdout
# (Zed, Cursor, Claude Desktop, etc.).
#
# Usage:
#   bin/ragex-mcp                          # basic startup
#   bin/ragex-mcp --project /path/to/code  # auto-analyze a project on startup
#   bin/ragex-mcp --log-level debug        # override log level
#
# Environment variables (all optional):
#   RAGEX_PROJECT          -- same as --project
#   RAGEX_LOG_LEVEL        -- same as --log-level (default: info)
#   RAGEX_EMBEDDING_MODEL  -- embedding model to use

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"

cd "$PROJECT_DIR"

# -- Defaults ---------------------------------------------------------------
PROJECT="${RAGEX_PROJECT:-}"
LOG_LEVEL="${RAGEX_LOG_LEVEL:-info}"

# -- Parse arguments --------------------------------------------------------
while [[ $# -gt 0 ]]; do
  case "$1" in
    --project)
      PROJECT="$2"
      shift 2
      ;;
    --project=*)
      PROJECT="${1#*=}"
      shift
      ;;
    --log-level)
      LOG_LEVEL="$2"
      shift 2
      ;;
    --log-level=*)
      LOG_LEVEL="${1#*=}"
      shift
      ;;
    --help|-h)
      cat <<'EOF'
Usage: ragex-mcp [--project PATH] [--log-level LEVEL]

Start Ragex as an MCP server communicating over stdio.

Options:
  --project PATH    Auto-analyze a project directory on startup
  --log-level LEVEL Set log level (debug|info|warning|error)

Environment:
  RAGEX_PROJECT          Same as --project
  RAGEX_LOG_LEVEL        Same as --log-level (default: info)
  RAGEX_EMBEDDING_MODEL  Embedding model to use
EOF
      exit 0
      ;;
    *)
      echo "Unknown option: $1" >&2
      exit 1
      ;;
  esac
done

# -- Environment for MCP stdio mode -----------------------------------------
export MIX_ENV=prod
export RAGEX_STDIO=1
export LOG_LEVEL="$LOG_LEVEL"

if [[ -n "$PROJECT" ]]; then
  export RAGEX_AUTO_ANALYZE="$PROJECT"
fi

# -- Detect running instance ------------------------------------------------
# If a Ragex server is already listening on the Unix socket, bridge to it
# instead of starting a second BEAM VM (which would OOM on GPU allocation).
SOCKET_PATH="/tmp/ragex_mcp.sock"

if [[ -S "$SOCKET_PATH" ]]; then
  # Try a lightweight ping via the socket to confirm it's alive.
  # Send MCP ping, read one response line, check for "result".
  PING='{"jsonrpc":"2.0","id":0,"method":"ping","params":{}}'
  # timeout 2s: if no response, server is stale
  PONG=$(echo "$PING" | timeout 2 socat - UNIX-CONNECT:"$SOCKET_PATH" 2>/dev/null | head -1)

  if echo "$PONG" | grep -q '"result"'; then
    echo "[ragex-mcp] Reusing running server via $SOCKET_PATH" >&2
    exec "$SCRIPT_DIR/ragex-bridge"
  fi
fi

# -- No running instance, start full server ---------------------------------

# Compile silently (all output to stderr so it never pollutes stdio JSON-RPC)
mix compile >&2 2>&1

# Run the server (only JSON-RPC goes to stdout)
exec mix run --no-halt --no-compile
