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

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

KV_ROOT="${CRYSTAL_KV_ROOT:-$HOME/Code/@applications/@ml/knowledge-platform}"
PLATFORM_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
KV_API_PORT=41233
REDIS_URL="redis://:kv_dev_password@localhost:26384"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
RESET='\033[0m'

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

usage() {
  echo -e "${BOLD}Crystal — Self-contained knowledge AI orchestration${RESET}"
  echo ""
  echo "Usage: ./run [command]"
  echo ""
  echo "Commands:"
  echo "  start       Full startup: infra -> register -> kv-api (default)"
  echo "  stop        Stop kv-api + docker compose down"
  echo "  status      Health check all components"
  echo "  register    Register Crystal-AI models with model-boss manifest"
  echo "  infra       Start only Docker containers (postgres, redis)"
  echo "  logs [svc]  Tail docker compose logs (optional: service name)"
  echo ""
}

# ===========================================================================
# Model Registration
# ===========================================================================

register_models() {
  log "Registering Crystal-AI models with model-boss..."
  python3 "$SCRIPT_DIR/scripts/register_models.py" 2>&1 || {
    warn "Model registration failed (non-fatal, continuing...)"
    return 0
  }
  ok "Models registered"
}

# ===========================================================================
# Infrastructure
# ===========================================================================

infra_up() {
  log "Starting infrastructure (postgres:25470, redis:26384)..."
  docker compose up -d

  log "Waiting for PostgreSQL..."
  local retries=0
  while ! docker exec crystal-postgres pg_isready -U lilith -q 2>/dev/null; do
    retries=$((retries + 1))
    if [ "$retries" -ge 30 ]; then
      err "PostgreSQL failed to become ready after 30s"
      exit 1
    fi
    sleep 1
  done
  ok "PostgreSQL ready"

  log "Waiting for Redis..."
  retries=0
  while ! docker exec crystal-redis redis-cli -a kv_dev_password ping 2>/dev/null | grep -q PONG; do
    retries=$((retries + 1))
    if [ "$retries" -ge 30 ]; then
      err "Redis failed to become ready after 30s"
      exit 1
    fi
    sleep 1
  done
  ok "Redis ready"

  ok "Infrastructure up"
}

infra_down() {
  log "Stopping infrastructure..."
  docker compose down
  ok "Infrastructure stopped"
}

# ===========================================================================
# KV API
# ===========================================================================

start_api() {
  local api_dir="$KV_ROOT/features/api/service"

  if [ ! -d "$api_dir" ]; then
    err "KV API directory not found: $api_dir"
    err "Set CRYSTAL_KV_ROOT to override the application root"
    exit 1
  fi

  log "Starting kv-api on port $KV_API_PORT..."
  cd "$api_dir"
  REDIS_URL="$REDIS_URL" \
  TRUTH_DB_HOST="${TRUTH_DB_HOST:-localhost}" \
  TRUTH_DB_PORT="${TRUTH_DB_PORT:-25470}" \
  TRUTH_DB_USER="${TRUTH_DB_USER:-lilith}" \
  TRUTH_DB_PASSWORD="${TRUTH_DB_PASSWORD:-kv_dev_password}" \
  TRUTH_DB_NAME="${TRUTH_DB_NAME:-truth_validation}" \
  LILITH_PROJECT_ROOT="$PLATFORM_ROOT" \
  DOCS_PATH="$PLATFORM_ROOT/docs" \
  LLM_ENDPOINT="${LLM_ENDPOINT:-http://localhost:8210}" \
  VERIFICATION_MODEL="${VERIFICATION_MODEL:-crystal-ai-3b}" \
  VERIFICATION_LLM_MODEL="${VERIFICATION_LLM_MODEL:-crystal-ai-3b}" \
  QA_MODEL="${QA_MODEL:-crystal-ai-qa-3b}" \
  PORT="$KV_API_PORT" \
  exec bun run dev
}

# ===========================================================================
# Status
# ===========================================================================

check_status() {
  echo -e "${BOLD}Crystal Status${RESET}"
  echo ""

  # PostgreSQL
  if docker exec crystal-postgres pg_isready -U lilith -q 2>/dev/null; then
    ok "PostgreSQL    :25470  healthy"
  else
    err "PostgreSQL    :25470  DOWN"
  fi

  # Redis
  if docker exec crystal-redis redis-cli -a kv_dev_password ping 2>/dev/null | grep -q PONG; then
    ok "Redis Stack   :26384  healthy"
  else
    err "Redis Stack   :26384  DOWN"
  fi

  # KV API
  if curl -sf "http://localhost:$KV_API_PORT/health" >/dev/null 2>&1; then
    ok "KV API        :$KV_API_PORT healthy"
  else
    warn "KV API        :$KV_API_PORT not running"
  fi

  # Models
  if [ -d "$SCRIPT_DIR/models" ] && ls "$SCRIPT_DIR/models"/*.gguf >/dev/null 2>&1; then
    local count
    count=$(ls "$SCRIPT_DIR/models"/*.gguf 2>/dev/null | wc -l)
    ok "Models                 $count GGUF file(s) found"
  else
    warn "Models                 no GGUF models"
  fi

  # Artifacts
  local artifacts="$KV_ROOT/.artifacts"
  if [ -d "$artifacts" ]; then
    ok "Artifacts              $artifacts"
  else
    warn "Artifacts              none (no pipeline runs yet)"
  fi

  echo ""
}

# ===========================================================================
# Main
# ===========================================================================

COMMAND="${1:-start}"
shift || true

case "$COMMAND" in
  start)
    infra_up
    register_models
    start_api
    ;;
  register)
    register_models
    ;;
  stop)
    # Stop kv-api if running (find by port)
    local_pid=$(lsof -ti :"$KV_API_PORT" 2>/dev/null || true)
    if [ -n "$local_pid" ]; then
      log "Stopping kv-api (PID $local_pid)..."
      kill "$local_pid" 2>/dev/null || true
      ok "kv-api stopped"
    fi
    infra_down
    ;;
  status)
    check_status
    ;;
  infra)
    infra_up
    ;;
  logs)
    docker compose logs -f "$@"
    ;;
  -h|--help|help)
    usage
    ;;
  *)
    err "Unknown command: $COMMAND"
    usage
    exit 1
    ;;
esac
