#!/usr/bin/env bash
set -euo pipefail

CHATDEV_REPO="https://github.com/OpenBMB/ChatDev.git"
CHATDEV_COMMIT="4fb2db0ea90375ce1059f44fe03ffbd191a7a169"
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
RUNTIME_ROOT="$SCRIPT_DIR/.runtime"
APP_DIR="$RUNTIME_ROOT/ChatDev"
ENV_FILE="$SCRIPT_DIR/.env"

fail() { printf '\nERROR: %s\n' "$*" >&2; exit 1; }

command -v docker >/dev/null 2>&1 || fail "Docker is not installed."
docker compose version >/dev/null 2>&1 || fail "The Docker Compose plugin is required ('docker compose', not the old 'docker-compose')."
docker info >/dev/null 2>&1 || fail "Docker is unavailable. Start it or fix Docker group permissions."

compose() { docker compose -f "$APP_DIR/compose.yml" --project-directory "$APP_DIR" "$@"; }

case "${1:-start}" in
  stop)
    [ -f "$APP_DIR/compose.yml" ] && compose down || echo "ChatDev has not been set up yet."
    exit 0 ;;
  status)
    [ -f "$APP_DIR/compose.yml" ] && compose ps || echo "ChatDev has not been set up yet."
    exit 0 ;;
  logs)
    [ -f "$APP_DIR/compose.yml" ] || fail "Run ./run.sh first."
    shift || true
    compose logs -f --tail 100 "$@"
    exit 0 ;;
  start|rebuild) ;;
  *) fail "Usage: ./run.sh [start|stop|status|logs [backend|frontend]|rebuild]" ;;
esac

command -v git >/dev/null 2>&1 || fail "Git is required."
[ -f "$ENV_FILE" ] || fail ".env is missing. Run: cp .env.example .env  Then edit API_KEY."
if grep -Eq '^(API_KEY=replace-|API_KEY=sk-your-|API_KEY=$)' "$ENV_FILE"; then
  fail "Replace the placeholder API_KEY in .env before starting."
fi

mkdir -p "$RUNTIME_ROOT"
if [ ! -d "$APP_DIR/.git" ]; then
  echo "==> Cloning the official ChatDev repository..."
  git clone "$CHATDEV_REPO" "$APP_DIR"
fi

echo "==> Checking out pinned ChatDev revision $CHATDEV_COMMIT"
git -C "$APP_DIR" fetch --depth 1 origin "$CHATDEV_COMMIT"
git -C "$APP_DIR" checkout --detach "$CHATDEV_COMMIT"
cp "$ENV_FILE" "$APP_DIR/.env"

if [ "${1:-start}" = "rebuild" ]; then
  echo "==> Rebuilding and starting ChatDev..."
  compose up -d --build
else
  echo "==> Starting ChatDev (the first build can take 10-20 minutes)..."
  compose up -d --build
fi

probe() {
  if command -v curl >/dev/null 2>&1; then curl -fsS http://localhost:5173 >/dev/null 2>&1
  elif command -v wget >/dev/null 2>&1; then wget -qO- http://localhost:5173 >/dev/null 2>&1
  else return 2
  fi
}

printf '==> Waiting for the ChatDev web console '
ready=0
for _ in $(seq 1 150); do
  set +e; probe; rc=$?; set -e
  if [ "$rc" -eq 0 ]; then ready=1; break; fi
  if [ "$rc" -eq 2 ]; then sleep 15; ready=1; break; fi
  printf '.'; sleep 2
done
printf '\n'

if [ "$ready" -ne 1 ]; then
  compose ps >&2 || true
  compose logs --tail 80 >&2 || true
  fail "ChatDev did not answer within five minutes after build. Run: ./run.sh logs"
fi

echo "==> ChatDev is ready: http://localhost:5173"
echo "==> Backend API:       http://localhost:6400"
command -v xdg-open >/dev/null 2>&1 && xdg-open http://localhost:5173 >/dev/null 2>&1 || true
printf '\nOpen Workflow -> ChatDev_v1, then Launch -> ChatDev_v1.\nStop: ./run.sh stop    Logs: ./run.sh logs\n'
