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

# Startet das zentrale, lokale LLM des Voice-Assistants als llama.cpp-Server
# (OpenAI-kompatibel). Dieses grosse, unzensierte Modell ist die Haupt-KI fuer
# den Provider "local-openai-compatible".
#
# Alles ueber ENV ueberschreibbar, z. B.:
#   HOST_PORT=8101 GPU_DEVICE=2 ./start-llm-server.sh
#   MODEL_REL_PATH="models/qwen3/anderes-modell.gguf" ./start-llm-server.sh

HF_HOME="${HF_HOME:-/home/dschlueter/nvme2n1p7_home/huggingface}"
MODEL_REL_PATH="${MODEL_REL_PATH:-models/qwen3/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive-Q4_K_M.gguf}"
IMAGE="${IMAGE:-ghcr.io/ggml-org/llama.cpp:server-cuda}"
CONTAINER_NAME="${CONTAINER_NAME:-va_llm}"
HOST_PORT="${HOST_PORT:-8001}"
CONTAINER_PORT="${CONTAINER_PORT:-8000}"
MODEL_ALIAS="${MODEL_ALIAS:-va_llm}"
GPU_DEVICE="${GPU_DEVICE:-1}"

echo "[*] Verwende HF_HOME = $HF_HOME"
echo "[*] Modell        = $MODEL_REL_PATH"
echo "[*] GPU device     = $GPU_DEVICE (ueberschreibbar: GPU_DEVICE=2 ./start-llm-server.sh)"
echo "[*] Port           = $HOST_PORT  | Alias = $MODEL_ALIAS | Container = $CONTAINER_NAME"
if [ ! -f "$HF_HOME/$MODEL_REL_PATH" ]; then
  echo "[!] Modell-Datei nicht gefunden: $HF_HOME/$MODEL_REL_PATH" >&2
  exit 1
fi

if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}\$"; then
  echo "[*] Stoppe existierenden Container $CONTAINER_NAME ..."
  docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
fi

echo "[*] Starte llama.cpp-Server (zentrale Voice-Assistant-KI) ..."
docker run -d \
  --gpus "\"device=${GPU_DEVICE}\"" \
  --name "$CONTAINER_NAME" \
  --restart unless-stopped \
  -e HF_HOME="/hf_home" \
  -v "$HF_HOME:/hf_home:ro" \
  -p "${HOST_PORT}:${CONTAINER_PORT}" \
  "$IMAGE" \
    -m "/hf_home/${MODEL_REL_PATH}" \
    --alias "${MODEL_ALIAS}" \
    -c 262144 \
    -n 16384 \
    --jinja \
    --reasoning on \
    --no-context-shift \
    --temp 0.65 \
    --top-p 0.80 \
    --top-k 20 \
    --min-p 0.01 \
    --repeat-penalty 1.05 \
    --main-gpu 0 \
    -ngl 999 \
    -fa on \
    --kv-unified \
    --cache-type-k q4_0 \
    --cache-type-v q4_0 \
    --batch-size 1024 \
    --ubatch-size 512 \
    --parallel 1 \
    --cont-batching \
    --host 0.0.0.0 \
    --port "$CONTAINER_PORT"

echo "[*] Warte auf Modell-Bereitschaft (Completion-Check, max. 300 s) ..."
MODEL_READY=0
for i in {1..150}; do
  HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 \
    -X POST "http://localhost:${HOST_PORT}/v1/chat/completions" \
    -H "Content-Type: application/json" \
    -d "{\"model\":\"${MODEL_ALIAS}\",\"messages\":[{\"role\":\"user\",\"content\":\"ping\"}],\"max_tokens\":1,\"temperature\":0.0,\"stream\":false}") || HTTP_CODE="000"
  if [ "$HTTP_CODE" = "200" ]; then MODEL_READY=1; break; fi
  echo "  [${i}/150] HTTP ${HTTP_CODE:-000} — Modell laedt noch, warte 2s ..."
  sleep 2
done

if [ "$MODEL_READY" -ne 1 ]; then
  echo "[!] Modell wurde nicht rechtzeitig bereit (kein HTTP 200 auf Completion)." >&2
  docker logs --tail 200 "$CONTAINER_NAME" || true
  exit 1
fi

echo "[*] Modell bereit — erster Completion-Request erfolgreich (HTTP 200)."
echo "[*] Server laeuft auf http://0.0.0.0:${HOST_PORT}/v1  (Alias: ${MODEL_ALIAS})"
echo "[*] Setze im Gateway:  LOCAL_LLM_BASE_URL=http://127.0.0.1:${HOST_PORT}/v1  LOCAL_LLM_MODEL=${MODEL_ALIAS}"
echo "[*] Stoppen mit:  scripts/llm-server/stop-llm-server.sh"
