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

COMMON_LIB_DIR="/opt/model-gateway/lib"

declare -a CANDIDATES=()

add_candidate() {
  local candidate="$1"
  [[ -n "$candidate" ]] || return 0
  local existing
  for existing in "${CANDIDATES[@]}"; do
    [[ "$existing" == "$candidate" ]] && return 0
  done
  CANDIDATES+=("$candidate")
}

add_candidate "${MODEL_GATEWAY_LLAMA_SERVER:-}"
add_candidate "$(command -v llama-server 2>/dev/null || true)"
add_candidate "/opt/llama.cpp/bin/llama-server"
add_candidate "/opt/llama.cpp/build/bin/llama-server"
add_candidate "/usr/local/bin/llama-server"
add_candidate "/usr/bin/llama-server"

build_runtime_ld_library_path() {
  local bin_dir="$1"
  local -a parts=(
    "$bin_dir"
    "$bin_dir/../lib64"
    "$bin_dir/../lib"
    "$bin_dir/../src"
    "$bin_dir/../ggml/src"
    "$bin_dir/../ggml/src/ggml-cpu"
    "$bin_dir/../ggml/src/ggml-cuda"
    "$bin_dir/../common"
    "$bin_dir/../tools/server"
    "$bin_dir/../../lib64"
    "$bin_dir/../../lib"
    "$COMMON_LIB_DIR"
    "/usr/local/lib64"
    "/usr/local/lib"
    "/usr/lib64"
    "/usr/lib/x86_64-linux-gnu"
    "/usr/local/cuda/lib64"
    "/usr/local/cuda/targets/x86_64-linux/lib"
  )

  local item
  local -a extra_parts=()
  if [[ -n "${MODEL_GATEWAY_LLAMA_LIBRARY_PATH:-}" ]]; then
    IFS=':' read -r -a extra_parts <<< "${MODEL_GATEWAY_LLAMA_LIBRARY_PATH}"
    for item in "${extra_parts[@]}"; do
      parts+=("$item")
    done
  fi
  if [[ -n "${LD_LIBRARY_PATH:-}" ]]; then
    IFS=':' read -r -a extra_parts <<< "${LD_LIBRARY_PATH}"
    for item in "${extra_parts[@]}"; do
      parts+=("$item")
    done
  fi

  local result=""
  for item in "${parts[@]}"; do
    [[ -n "$item" ]] || continue
    result="${result:+$result:}$item"
  done
  printf '%s' "$result"
}

try_exec() {
  local bin="$1"
  shift
  [[ -x "$bin" ]] || return 1

  local bin_dir
  bin_dir="$(cd "$(dirname "$bin")" && pwd)"

  local runtime_ld_library_path
  runtime_ld_library_path="$(build_runtime_ld_library_path "$bin_dir")"

  if command -v ldd >/dev/null 2>&1; then
    if LD_LIBRARY_PATH="$runtime_ld_library_path" ldd "$bin" 2>/dev/null | grep -q "not found"; then
      echo "Skipping llama-server because shared libraries are missing: $bin" >&2
      LD_LIBRARY_PATH="$runtime_ld_library_path" ldd "$bin" 2>/dev/null | grep "not found" >&2 || true
      return 1
    fi
  fi

  export LD_LIBRARY_PATH="$runtime_ld_library_path"
  exec "$bin" "$@"
}

for candidate in "${CANDIDATES[@]}"; do
  try_exec "$candidate" "$@" || true
done

cat >&2 <<'EOF'
No usable external llama-server runtime was found.

Install a CUDA-compatible llama.cpp runtime first, then configure this service:

  sudo model-gateway-set-llama-server /opt/llama.cpp/build/bin/llama-server
  sudo systemctl restart model-gateway

The launcher also checks:
  /opt/llama.cpp/bin/llama-server
  /opt/llama.cpp/build/bin/llama-server
  /usr/local/bin/llama-server
  /usr/bin/llama-server
EOF
exit 127
