#!/usr/bin/env bash

set -euo pipefail

ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
STATE_DIR="$ROOT_DIR/state"
RUNTIME_ENV="$STATE_DIR/runtime.env"

load_runtime_env() {
  if [ -f "$RUNTIME_ENV" ]; then
    # shellcheck disable=SC1090
    . "$RUNTIME_ENV"
  fi

  : "${COURSEWARE_STATE_DIR:=$STATE_DIR}"
  : "${COURSEWARE_BIND_HOST:=127.0.0.1}"
  : "${COURSEWARE_URL_HOST:=127.0.0.1}"
  : "${COURSEWARE_PROMPTFOO_PORT:=15500}"
  : "${COURSEWARE_WIKI_PORT:=80}"
  : "${NODE_RUNTIME_BIN_DIR:=$COURSEWARE_STATE_DIR/tools/node-runtime/node_modules/node/bin}"
  : "${PROMPTFOO_DIR:=$COURSEWARE_STATE_DIR/lab6}"
  : "${WIKI_DIR:=$COURSEWARE_STATE_DIR/repos/LLM-Labs}"
  : "${LLAMA_CPP_BIN_DIR:=$COURSEWARE_STATE_DIR/repos/llama.cpp/build/bin}"

  if [ -n "${OLLAMA_BIN:-}" ] && [[ "$OLLAMA_BIN" != */* ]] && command -v "$OLLAMA_BIN" >/dev/null 2>&1; then
    OLLAMA_BIN=$(command -v "$OLLAMA_BIN")
  fi
}

ensure_runtime_env() {
  if [ ! -f "$RUNTIME_ENV" ]; then
    echo "Missing $RUNTIME_ENV. Run ./labctl up first." >&2
    exit 1
  fi
}

service_list() {
  printf '%s\n' \
    "ollama" \
    "open-webui" \
    "transformerlab" \
    "chunkviz" \
    "embedding-atlas" \
    "unsloth" \
    "promptfoo" \
    "wiki"
}

service_pid_file() {
  printf '%s/run/%s.pid\n' "$STATE_DIR" "${1//-/_}"
}

service_log_file() {
  printf '%s/logs/%s.log\n' "$STATE_DIR" "${1//-/_}"
}

service_port() {
  case "$1" in
    ollama) printf '%s\n' "${COURSEWARE_OLLAMA_PORT}" ;;
    open-webui) printf '%s\n' "${COURSEWARE_OPEN_WEBUI_PORT}" ;;
    transformerlab) printf '%s\n' "${COURSEWARE_TRANSFORMERLAB_PORT}" ;;
    chunkviz) printf '%s\n' "${COURSEWARE_CHUNKVIZ_PORT}" ;;
    embedding-atlas) printf '%s\n' "${COURSEWARE_EMBEDDING_ATLAS_PORT}" ;;
    unsloth) printf '%s\n' "${COURSEWARE_UNSLOTH_PORT}" ;;
    promptfoo) printf '%s\n' "${COURSEWARE_PROMPTFOO_PORT}" ;;
    wiki) printf '%s\n' "${COURSEWARE_WIKI_PORT}" ;;
    *) return 1 ;;
  esac
}

service_url() {
  case "$1" in
    ollama) printf 'http://%s:%s\n' "$COURSEWARE_URL_HOST" "$COURSEWARE_OLLAMA_PORT" ;;
    open-webui) printf 'http://%s:%s\n' "$COURSEWARE_URL_HOST" "$COURSEWARE_OPEN_WEBUI_PORT" ;;
    transformerlab) printf 'http://%s:%s\n' "$COURSEWARE_URL_HOST" "$COURSEWARE_TRANSFORMERLAB_PORT" ;;
    chunkviz) printf 'http://%s:%s\n' "$COURSEWARE_URL_HOST" "$COURSEWARE_CHUNKVIZ_PORT" ;;
    embedding-atlas) printf 'http://%s:%s\n' "$COURSEWARE_URL_HOST" "$COURSEWARE_EMBEDDING_ATLAS_PORT" ;;
    unsloth) printf 'http://%s:%s\n' "$COURSEWARE_URL_HOST" "$COURSEWARE_UNSLOTH_PORT" ;;
    promptfoo) printf 'http://%s:%s\n' "$COURSEWARE_URL_HOST" "$COURSEWARE_PROMPTFOO_PORT" ;;
    wiki) printf 'http://%s:%s\n' "$COURSEWARE_URL_HOST" "$COURSEWARE_WIKI_PORT" ;;
    *) return 1 ;;
  esac
}

service_command() {
  case "$1" in
    ollama)
      printf 'exec env OLLAMA_HOST=%s:%s OLLAMA_MODELS="%s" "%s" serve' \
        "$COURSEWARE_BIND_HOST" \
        "$COURSEWARE_OLLAMA_PORT" \
        "$OLLAMA_MODELS_DIR" \
        "$OLLAMA_BIN"
      ;;
    open-webui)
      printf 'exec env DATA_DIR="%s" OLLAMA_BASE_URL=http://%s:%s "%s/bin/open-webui" serve --host %s --port %s' \
        "$OPEN_WEBUI_DATA_DIR" \
        "$COURSEWARE_URL_HOST" \
        "$COURSEWARE_OLLAMA_PORT" \
        "$OPEN_WEBUI_VENV" \
        "$COURSEWARE_BIND_HOST" \
        "$COURSEWARE_OPEN_WEBUI_PORT"
      ;;
    transformerlab)
      printf 'export PATH="%s/envs/transformerlab/bin:$PATH"; export VIRTUAL_ENV="%s/envs/transformerlab"; export CONDA_PREFIX="%s/envs/transformerlab"; cd "%s/src" && exec ./run.sh -c -h %s -p %s' \
        "$TRANSFORMERLAB_DIR" \
        "$TRANSFORMERLAB_DIR" \
        "$TRANSFORMERLAB_DIR" \
        "$TRANSFORMERLAB_DIR" \
        "$COURSEWARE_BIND_HOST" \
        "$COURSEWARE_TRANSFORMERLAB_PORT"
      ;;
    chunkviz)
      printf 'cd "%s" && PATH="%s:$PATH" exec "./node_modules/.bin/serve" build -s -n -L -l tcp://%s:%s' \
        "$CHUNKVIZ_DIR" \
        "$NODE_RUNTIME_BIN_DIR" \
        "$COURSEWARE_BIND_HOST" \
        "$COURSEWARE_CHUNKVIZ_PORT"
      ;;
    embedding-atlas)
      printf 'exec "%s/bin/embedding-atlas" "%s" --text "Scenario" --host %s --port %s' \
        "$EMBEDDING_ATLAS_VENV" \
        "$TTPS_DATASET_PATH" \
        "$COURSEWARE_BIND_HOST" \
        "$COURSEWARE_EMBEDDING_ATLAS_PORT"
      ;;
    unsloth)
      printf 'exec "%s" studio -H %s -p %s' \
        "$UNSLOTH_BIN" \
        "$COURSEWARE_BIND_HOST" \
        "$COURSEWARE_UNSLOTH_PORT"
      ;;
    promptfoo)
      printf 'cd "%s" && PATH="%s:$PATH" COURSEWARE_BIND_HOST=%s "%s" view . --port %s --no' \
        "$PROMPTFOO_DIR" \
        "$NODE_RUNTIME_BIN_DIR" \
        "$COURSEWARE_BIND_HOST" \
        "$PROMPTFOO_BIN" \
        "$COURSEWARE_PROMPTFOO_PORT"
      ;;
    wiki)
      printf 'cd "%s" && PATH="%s:$PATH" exec "./node_modules/.bin/next" start --hostname %s --port %s' \
        "$WIKI_DIR" \
        "$NODE_RUNTIME_BIN_DIR" \
        "$COURSEWARE_BIND_HOST" \
        "$COURSEWARE_WIKI_PORT"
      ;;
    *)
      return 1
      ;;
  esac
}
