#!/usr/bin/env bash
# ──────────────────────────────────────────────────────────────
# start-with-neo.sh — 一键启动 Shipyard Neo Bay + AstrBot
#
# Usage:
#   bash scripts/start-with-neo.sh            # 默认 Bay :8114
#   BAY_PORT=9000 bash scripts/start-with-neo.sh  # 自定义端口
# ──────────────────────────────────────────────────────────────
set -euo pipefail

# ── 路径 ──────────────────────────────────────────────────────
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ASTRBOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
# shipyard-neo mono-repo root is one level above AstrBot
NEO_ROOT="$(cd "$ASTRBOT_DIR/.." && pwd)"
BAY_DIR="$NEO_ROOT/pkgs/bay"

BAY_PORT="${BAY_PORT:-8114}"
BAY_HOST="0.0.0.0"
BAY_PID=""
BAY_API_KEY=""  # Populated after Bay starts from credentials.json

# ── 颜色 ──────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

log()  { echo -e "${CYAN}[neo]${NC} $*"; }
ok()   { echo -e "${GREEN}[neo]${NC} $*"; }
warn() { echo -e "${YELLOW}[neo]${NC} $*"; }
err()  { echo -e "${RED}[neo]${NC} $*" >&2; }

# ── 清理函数 ──────────────────────────────────────────────────
cleanup() {
    log "Shutting down..."
    if [[ -n "$BAY_PID" ]] && kill -0 "$BAY_PID" 2>/dev/null; then
        log "Stopping Bay (PID $BAY_PID)..."
        kill "$BAY_PID" 2>/dev/null || true
        wait "$BAY_PID" 2>/dev/null || true
    fi
    ok "All services stopped."
}
trap cleanup EXIT INT TERM

# ── 检查前置条件 ──────────────────────────────────────────────
check_prerequisites() {
    log "Checking prerequisites..."

    if [[ ! -d "$BAY_DIR" ]]; then
        err "Bay directory not found: $BAY_DIR"
        err "Expected shipyard-neo mono-repo at: $NEO_ROOT"
        exit 1
    fi

    if ! command -v uv &>/dev/null; then
        err "'uv' is not installed. Please install it first."
        exit 1
    fi

    # Check Docker access (try without sudo first, then with sudo)
    if docker info &>/dev/null 2>&1; then
        ok "Docker is accessible."
    elif sudo docker info &>/dev/null 2>&1; then
        warn "Docker requires sudo. Bay may need socket permissions."
        warn "If Bay fails to connect to Docker, run: sudo chmod 666 /var/run/docker.sock"
    else
        err "Docker is not accessible. Please install Docker or fix permissions."
        exit 1
    fi

    # Check Bay venv
    if [[ ! -d "$BAY_DIR/.venv" ]]; then
        log "Bay venv not found. Running 'uv sync' in $BAY_DIR ..."
        (cd "$BAY_DIR" && uv sync)
    fi

    ok "Prerequisites OK."
}

# ── 生成 Bay config.yaml（如不存在）────────────────────────────
ensure_bay_config() {
    local config_file="$BAY_DIR/config.yaml"

    if [[ -f "$config_file" ]]; then
        ok "Bay config.yaml already exists."
        return
    fi

    log "Generating Bay config.yaml for local development..."

    cat > "$config_file" << 'BAYCONFIG'
# Bay Local Development Config (auto-generated by start-with-neo.sh)
# For full reference see config.yaml.example

server:
  host: "0.0.0.0"
  port: 8114

database:
  url: "sqlite+aiosqlite:///./bay.db"
  echo: false

driver:
  type: docker
  image_pull_policy: if_not_present
  docker:
    socket: "unix:///var/run/docker.sock"
    connect_mode: host_port
    host_address: "127.0.0.1"
    publish_ports: true
    host_port: null
    network: null

cargo:
  root_path: "/var/lib/bay/cargos"
  default_size_limit_mb: 1024
  mount_path: "/workspace"

# Security: auto-provision mode
# Bay generates sk-bay-* key on first boot → credentials.json
security:
  allow_anonymous: false

profiles:
  - id: python-default
    description: "Standard Python sandbox"
    image: "ghcr.io/astrbotdevs/shipyard-neo-ship:latest"
    runtime_type: ship
    runtime_port: 8123
    resources:
      cpus: 1.0
      memory: "1g"
    capabilities:
      - filesystem
      - shell
      - python
    idle_timeout: 1800
    env: {}

gc:
  enabled: true
  run_on_startup: true
  interval_seconds: 300
  idle_session:
    enabled: true
  expired_sandbox:
    enabled: true
  orphan_cargo:
    enabled: true
  orphan_container:
    enabled: false
BAYCONFIG

    ok "Bay config.yaml created at $config_file"
}

# ── 拉取 Ship 镜像 ───────────────────────────────────────────
ensure_ship_image() {
    local image="ghcr.io/astrbotdevs/shipyard-neo-ship:latest"
    log "Checking Ship image: $image ..."

    if docker image inspect "$image" &>/dev/null 2>&1 || \
       sudo docker image inspect "$image" &>/dev/null 2>&1; then
        ok "Ship image is available locally."
    else
        log "Pulling Ship image (this may take a while)..."
        if docker pull "$image" 2>/dev/null || sudo docker pull "$image" 2>/dev/null; then
            ok "Ship image pulled successfully."
        else
            warn "Failed to pull Ship image. Bay will try to pull it on first sandbox creation."
        fi
    fi
}

# ── 启动 Bay ──────────────────────────────────────────────────
start_bay() {
    log "Starting Bay on :$BAY_PORT ..."

    (cd "$BAY_DIR" && BAY_DATA_DIR="$BAY_DIR" uv run uvicorn app.main:app \
        --host "$BAY_HOST" \
        --port "$BAY_PORT" \
        --reload \
        2>&1 | sed "s/^/  ${CYAN}[bay]${NC} /") &
    BAY_PID=$!

    log "Bay started (PID $BAY_PID), waiting for health check..."

    # Wait for Bay to become healthy
    local max_wait=30
    local waited=0
    while [[ $waited -lt $max_wait ]]; do
        if curl -sf "http://127.0.0.1:$BAY_PORT/health" &>/dev/null; then
            ok "Bay is healthy at http://127.0.0.1:$BAY_PORT"
            return
        fi
        # Check if process is still alive
        if ! kill -0 "$BAY_PID" 2>/dev/null; then
            err "Bay process died unexpectedly. Check the output above."
            exit 1
        fi
        sleep 1
        waited=$((waited + 1))
    done

    err "Bay did not become healthy within ${max_wait}s."
    err "It may still be starting — check http://127.0.0.1:$BAY_PORT/health"
}

# ── 读取 Bay 自动生成的凭证 ───────────────────────────────────
read_bay_credentials() {
    local cred_file="$BAY_DIR/credentials.json"

    # Wait briefly for credentials.json to appear (Bay writes it during startup)
    local max_wait=5
    local waited=0
    while [[ $waited -lt $max_wait ]]; do
        if [[ -f "$cred_file" ]]; then
            break
        fi
        sleep 1
        waited=$((waited + 1))
    done

    if [[ -f "$cred_file" ]]; then
        # Extract api_key using python (always available) — no jq dependency
        BAY_API_KEY=$(python3 -c "
import json, sys
try:
    d = json.load(open('$cred_file'))
    print(d.get('api_key', ''))
except Exception:
    print('')
" 2>/dev/null || echo "")

        if [[ -n "$BAY_API_KEY" ]]; then
            ok "Auto-provisioned API key loaded from credentials.json"
        else
            warn "credentials.json found but api_key is empty"
        fi
    else
        warn "credentials.json not found — Bay may be using an existing key or anonymous mode"
        warn "Check Bay logs above for the API key, or look at: $cred_file"
    fi
}

# ── 打印 AstrBot 配置提示 ────────────────────────────────────
print_astrbot_config_hint() {
    echo ""
    echo -e "${GREEN}════════════════════════════════════════════════════════════${NC}"
    echo -e "${GREEN}  Shipyard Neo Bay is running at http://127.0.0.1:$BAY_PORT ${NC}"
    echo -e "${GREEN}════════════════════════════════════════════════════════════${NC}"
    echo ""
    if [[ -n "$BAY_API_KEY" ]]; then
        echo -e "  ${CYAN}Bay API Key (auto-generated):${NC}"
        echo -e "  ${YELLOW}$BAY_API_KEY${NC}"
        echo ""
    fi
    echo -e "  ${CYAN}AstrBot Dashboard 配置指引：${NC}"
    echo -e "  1. AI 配置 → Agent Computer Use"
    echo -e "     • Computer Use Runtime → ${YELLOW}沙箱${NC}"
    echo -e "     • 沙箱环境驱动器        → ${YELLOW}Shipyard Neo${NC}"
    echo -e "     • Shipyard Neo API Endpoint → ${YELLOW}http://127.0.0.1:$BAY_PORT${NC}"
    if [[ -n "$BAY_API_KEY" ]]; then
        echo -e "     • Shipyard Neo Access Token → ${YELLOW}$BAY_API_KEY${NC}"
    else
        echo -e "     • Shipyard Neo Access Token → ${YELLOW}（查看 Bay 日志获取 key）${NC}"
    fi
    echo -e "     • Shipyard Neo Profile     → ${YELLOW}python-default${NC}"
    echo ""
}

# ── 启动 AstrBot ──────────────────────────────────────────────
start_astrbot() {
    log "Starting AstrBot..."
    cd "$ASTRBOT_DIR"
    uv run main.py
}

# ── 主流程 ────────────────────────────────────────────────────
main() {
    echo ""
    echo -e "${CYAN}╔══════════════════════════════════════════╗${NC}"
    echo -e "${CYAN}║   Shipyard Neo + AstrBot Quick Start    ║${NC}"
    echo -e "${CYAN}╚══════════════════════════════════════════╝${NC}"
    echo ""

    check_prerequisites
    ensure_bay_config
    ensure_ship_image
    start_bay
    read_bay_credentials
    print_astrbot_config_hint
    start_astrbot
}

main "$@"
