#!/usr/bin/env bash
# PnyxMind Connect for macOS and Linux: puts the model on your own computer (Ollama or LM Studio) into a PnyxMind case.
# It opens a private https address to your model with a Cloudflare tunnel and prints it, ready to paste in
# PnyxMind, Connections, "Your own model". Nothing is installed system-wide: cloudflared is kept in ~/.pnyxmind.
# Close this window (or press Ctrl+C) and the address stops working at once.
set -euo pipefail

say() { printf '%s\n' "$*"; }
dir="$HOME/.pnyxmind"; mkdir -p "$dir"

# 1. Which program serves the model: Ollama answers on port 11434, LM Studio on 1234.
port=""; name=""
if curl -fsS -m 3 http://localhost:11434/api/tags >/dev/null 2>&1; then port=11434; name="Ollama"
elif curl -fsS -m 3 http://localhost:1234/v1/models >/dev/null 2>&1; then port=1234; name="LM Studio"
fi
if [ -z "$port" ]; then
  say "Neither Ollama nor LM Studio is running on this computer."
  say " - Ollama: open the Ollama app (or run: ollama serve), then run this again."
  say " - LM Studio: open it, go to Developer, and switch on 'Start server', then run this again."
  exit 1
fi
say "Found $name on port $port."

# 2. cloudflared, Cloudflare's own tunnel program, downloaded once from Cloudflare's GitHub releases.
cf="$(command -v cloudflared || true)"
if [ -z "$cf" ]; then
  cf="$dir/cloudflared"
  if [ ! -x "$cf" ]; then
    os="$(uname -s | tr '[:upper:]' '[:lower:]')"; arch="$(uname -m)"
    case "$arch" in x86_64|amd64) arch=amd64 ;; arm64|aarch64) arch=arm64 ;; *) say "Unsupported processor: $arch"; exit 1 ;; esac
    base="https://github.com/cloudflare/cloudflared/releases/latest/download"
    say "Downloading cloudflared from Cloudflare (once)..."
    if [ "$os" = darwin ]; then
      curl -fsSL "$base/cloudflared-darwin-$arch.tgz" | tar -xz -C "$dir"
    else
      curl -fsSL -o "$cf" "$base/cloudflared-linux-$arch"
    fi
    chmod +x "$cf"
  fi
fi

# 3. The tunnel. It answers only while this window is open.
log="$dir/tunnel.log"; : > "$log"
"$cf" tunnel --no-autoupdate --url "http://localhost:$port" --http-host-header "localhost:$port" >"$log" 2>&1 &
pid=$!
trap 'kill $pid 2>/dev/null; say ""; say "Tunnel closed. PnyxMind can no longer reach your model."' EXIT
url=""
for _ in $(seq 1 30); do
  url="$(grep -Eo 'https://[a-z0-9-]+\.trycloudflare\.com' "$log" | head -1 || true)"
  [ -n "$url" ] && break
  sleep 1
done
if [ -z "$url" ]; then say "The tunnel did not start. Details:"; tail -20 "$log"; exit 1; fi

say ""
say "=============================================================="
say "  Your address for PnyxMind:  $url"
say "=============================================================="
say "Paste it in PnyxMind, Connections, 'Your own model', and pick the model."
if [ "$port" = 11434 ]; then
  say "Models on this computer:"; curl -fsS -m 5 http://localhost:11434/api/tags | grep -Eo '"name":"[^"]+"' | cut -d'"' -f4 | sed 's/^/  - /' || true
fi
say ""
say "Keep this window open while your case runs. Close it to stop."
wait $pid
