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

# ============================================================================
# Meilisearch setup for Jellyfin (bare Debian)
# ----------------------------------------------------------------------------
# Installs Meilisearch, creates a dedicated service user, generates a master
# key, writes a config file + systemd unit, and drops a Jellyfin environment
# override so the jellyfin-plugin-meilisearch plugin auto-discovers the
# instance via MEILI_URL / MEILI_MASTER_KEY.
# ============================================================================

# ── Tunables (override via environment before running) ──────────────────────
MEILI_BIND="${MEILI_BIND:-127.0.0.1:7700}"          # listen address
MEILI_DB_PATH="${MEILI_DB_PATH:-/var/lib/meilisearch/data}"
MEILI_DUMP_DIR="${MEILI_DUMP_DIR:-/var/lib/meilisearch/dumps}"
MEILI_SNAP_DIR="${MEILI_SNAP_DIR:-/var/lib/meilisearch/snapshots}"
MEILI_CONFIG="/etc/meilisearch.toml"
JELLYFIN_ENV_DIR="/etc/jellyfin"
JELLYFIN_ENV_FILE="${JELLYFIN_ENV_DIR}/meilisearch.env"
# If you already have a master key you want to reuse, export MEILI_MASTER_KEY
# before running this script. Otherwise one will be generated.

# ── Preflight ───────────────────────────────────────────────────────────────
if [[ $EUID -ne 0 ]]; then
  echo "ERROR: Please run this script as root (or with sudo)." >&2
  exit 1
fi

echo "==> Updating package lists…"
apt-get update -qq

echo "==> Installing prerequisites…"
apt-get install -y -qq curl openssl >/dev/null

# ── Install Meilisearch via official APT repo ───────────────────────────────
if command -v meilisearch &>/dev/null; then
  echo "==> Meilisearch binary already present: $(meilisearch --version 2>&1 | head -1)"
else
  echo "==> Adding Meilisearch APT repository…"
  echo "deb [trusted=yes] https://apt.fury.io/meilisearch/ /" \
    | tee /etc/apt/sources.list.d/fury.list >/dev/null
  apt-get update -qq
  echo "==> Installing Meilisearch…"
  apt-get install -y -qq meilisearch >/dev/null
  echo "    Installed: $(meilisearch --version 2>&1 | head -1)"
fi

# ── Create service user ────────────────────────────────────────────────────
if id meilisearch &>/dev/null; then
  echo "==> System user 'meilisearch' already exists."
else
  echo "==> Creating system user 'meilisearch'…"
  useradd -r -s /usr/sbin/nologin -d /var/lib/meilisearch -m meilisearch
fi

# ── Data directories ───────────────────────────────────────────────────────
echo "==> Setting up data directories…"
mkdir -p "$MEILI_DB_PATH" "$MEILI_DUMP_DIR" "$MEILI_SNAP_DIR"
chown -R meilisearch:meilisearch /var/lib/meilisearch
chmod 750 /var/lib/meilisearch

# ── Master key ─────────────────────────────────────────────────────────────
if [[ -z "${MEILI_MASTER_KEY:-}" ]]; then
  MEILI_MASTER_KEY="$(openssl rand -hex 24)"
  echo "==> Generated master key (save this somewhere safe):"
  echo "    $MEILI_MASTER_KEY"
else
  echo "==> Using provided MEILI_MASTER_KEY."
fi

# ── Config file ────────────────────────────────────────────────────────────
echo "==> Writing config to ${MEILI_CONFIG}…"
cat > "$MEILI_CONFIG" <<TOML
# /etc/meilisearch.toml — managed by setup script
env = "production"
master_key = "${MEILI_MASTER_KEY}"
http_addr = "${MEILI_BIND}"
db_path = "${MEILI_DB_PATH}"
dump_dir = "${MEILI_DUMP_DIR}"
snapshot_dir = "${MEILI_SNAP_DIR}"
# Uncomment to enable scheduled snapshots (every 24 h by default):
# schedule_snapshot = true
TOML
chmod 640 "$MEILI_CONFIG"
chown root:meilisearch "$MEILI_CONFIG"

# ── Systemd service ────────────────────────────────────────────────────────
echo "==> Installing systemd service…"
cat > /etc/systemd/system/meilisearch.service <<UNIT
[Unit]
Description=Meilisearch search engine
After=network.target

[Service]
Type=simple
User=meilisearch
Group=meilisearch
WorkingDirectory=/var/lib/meilisearch
ExecStart=/usr/bin/meilisearch --config-file-path ${MEILI_CONFIG}
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
UNIT

systemctl daemon-reload
systemctl enable --now meilisearch
echo "==> Meilisearch service started."

# ── Wait for readiness ─────────────────────────────────────────────────────
echo -n "==> Waiting for Meilisearch to become ready"
for i in $(seq 1 30); do
  if curl -sf "http://${MEILI_BIND}/health" >/dev/null 2>&1; then
    echo " OK"
    break
  fi
  echo -n "."
  sleep 1
done

# Quick health check
HEALTH="$(curl -sf "http://${MEILI_BIND}/health" || true)"
if echo "$HEALTH" | grep -q "available"; then
  echo "==> Meilisearch is healthy."
else
  echo "WARNING: Could not confirm Meilisearch health. Check 'journalctl -u meilisearch'." >&2
fi

# ── Jellyfin environment override ──────────────────────────────────────────
# The jellyfin-plugin-meilisearch plugin reads MEILI_URL and MEILI_MASTER_KEY
# from the Jellyfin process environment. The cleanest way to inject them on a
# bare-metal install is a systemd drop-in.
echo "==> Configuring Jellyfin environment for the Meilisearch plugin…"

JELLYFIN_SERVICE="jellyfin.service"
DROPIN_DIR="/etc/systemd/system/${JELLYFIN_SERVICE}.d"
mkdir -p "$DROPIN_DIR"

cat > "${DROPIN_DIR}/meilisearch.conf" <<DROPIN
[Service]
Environment="MEILI_URL=http://${MEILI_BIND}"
Environment="MEILI_MASTER_KEY=${MEILI_MASTER_KEY}"
DROPIN

systemctl daemon-reload

# Restart Jellyfin only if it is already running
if systemctl is-active --quiet "$JELLYFIN_SERVICE" 2>/dev/null; then
  echo "==> Restarting Jellyfin to pick up new environment…"
  systemctl restart "$JELLYFIN_SERVICE"
else
  echo "==> Jellyfin is not currently running; it will pick up the env vars on next start."
fi

# ── Summary ────────────────────────────────────────────────────────────────
cat <<EOF

============================================================
  Setup complete!
============================================================

  Meilisearch
    URL  : http://${MEILI_BIND}
    Key  : ${MEILI_MASTER_KEY}
    Config : ${MEILI_CONFIG}
    Data   : ${MEILI_DB_PATH}
    Service: systemctl status meilisearch

  Jellyfin integration
    Drop-in: ${DROPIN_DIR}/meilisearch.conf
    The plugin will auto-detect the instance via
    MEILI_URL and MEILI_MASTER_KEY env vars.

  Next steps
    1. Install the plugin in Jellyfin using this repo URL:
       https://raw.githubusercontent.com/arnesacnussem/jellyfin-plugin-meilisearch/refs/heads/master/manifest.json
    2. Restart Jellyfin if you haven't already.
    3. Open the plugin settings in Jellyfin and click Save —
       verify the status shows "ok".

EOF
