#!/bin/bash
# The comment above is shebang, DO NOT REMOVE
DEV_ABSPATH="$(readlink -f "${BASH_SOURCE[0]}")"
if [[ "$OSTYPE" == "darwin"* ]]; then
    # echo "In macOS server sed START"
    # echo "SERVER_ABSPATH: $SERVER_ABSPATH"
    sed -i '' 's/\r//g' "$DEV_ABSPATH"
    # echo "In macOS server sed END"
else
    # echo "NOT in macOS server START"
    # echo "SERVER_ABSPATH: $SERVER_ABSPATH"
    sed -i 's/\r//g' "$DEV_ABSPATH"
    # echo "NOT in macOS server START"
fi
chmod +x "$DEV_ABSPATH"

PROJECT_ROOT_ABSPATH="$(dirname "$(dirname "$DEV_ABSPATH")")"
BACKEND_DIR_ABSPATH="$PROJECT_ROOT_ABSPATH/backend"

# Cleanup function on exit
cleanup() {
    echo "Shutting down..."
    cd - > /dev/null 2>&1
}
trap cleanup EXIT INT TERM

# --- Create virtual environment if it doesn't exist ---
VENV_DIR="$BACKEND_DIR_ABSPATH/.venv"
if [[ ! -d "$VENV_DIR" ]]; then
    echo "Creating virtual environment..."
    python3 -m venv "$VENV_DIR"
fi
source "$VENV_DIR/bin/activate"

# --- Install custom debugger module if not already installed ---
DEBUGGER_DIR_ABSPATH="$PROJECT_ROOT_ABSPATH/debugger"
if ! pip3 show debug > /dev/null 2>&1; then
    echo "Installing debugger module..."
    cd "$DEBUGGER_DIR_ABSPATH"
    pip3 install -e .
    if [[ $? -ne 0 ]]; then
        echo "Failed to install debugger module."
        exit 1
    fi
fi

# --- Install Python dependencies ---
echo "Installing dependencies..."
cd "$BACKEND_DIR_ABSPATH"
pip3 install -r requirements.txt
if [[ $? -ne 0 ]]; then
    echo "Failed to install Python dependencies."
    exit 1
fi

# --- Start the backend server ---
# IMPORTANT: --reload-exclude must cover every path the running backend
# itself may WRITE to. Without this, the App Builder agent writing into
# a workspace's backend (e.g. backend/data/outputs_workspace/<ws>/backend/
# apps/chat/chat.py) triggers WatchFiles, which reloads uvicorn,
# which closes the agent's WebSocket mid-stream — visible to the user
# as the agent randomly "stopping" and needing a Resume.
#
# Caveat about uvicorn's pattern semantics: glob strings like `*/data/*`
# get matched via `Path.match`, which is RIGHT-anchored and doesn't
# match deep paths. Only `--reload-exclude` values that resolve to a
# real directory at config time get added to uvicorn's dir-exclude list
# (compared via `dir in path.parents`). So we pass ABSOLUTE paths to
# the dirs we want to exclude — those are the only patterns uvicorn's
# WatchFilesReload actually honors for "anywhere under this tree".
echo "Starting backend server on http://0.0.0.0:8324 ..."
cd "$PROJECT_ROOT_ABSPATH"

UVICORN_EXCLUDE_ARGS=(--reload-exclude '*.pyc')
for d in \
    "$BACKEND_DIR_ABSPATH/data" \
    "$BACKEND_DIR_ABSPATH/mcp-bundles" \
    "$BACKEND_DIR_ABSPATH/apps/outputs/webapp_template" \
; do
    if [[ -d "$d" ]]; then
        UVICORN_EXCLUDE_ARGS+=(--reload-exclude "$d")
    fi
done

# --reload is purely a dev-loop convenience — auto-restart on source
# edits. Useless for end users running the packaged DMG (no source to
# edit) and actively harmful: WatchFiles uses real fs handles, the
# reload supervisor adds a couple hundred MB of resident memory, and
# every reload tears down running agent WebSockets. Only enable it
# when the top-level run.sh has set OPENSWARM_DEV=1 (which the dev
# launcher does). Packaged builds leave it unset → fast, lean,
# single-process uvicorn.
if [[ "${OPENSWARM_DEV:-}" == "1" ]]; then
    echo "OPENSWARM_DEV=1 detected — running uvicorn with --reload."
    python3 -m uvicorn backend.main:app --host 0.0.0.0 --port 8324 --reload \
        --reload-dir "$BACKEND_DIR_ABSPATH" \
        "${UVICORN_EXCLUDE_ARGS[@]}"
else
    python3 -m uvicorn backend.main:app --host 0.0.0.0 --port 8324
fi
