#!/bin/bash
# install_for_jruby - Installer for the JRuby radio automation stack.
#
# Derives its service name from the directory it lives in, e.g.
#   /srv/radio/install_for_jruby  ->  radio.service
# Prompts for a storage root and writes a complete config.json.
# Creates media subdirectories (music, podcasts, jingles, announcements),
# state/ and logs/ under the storage root, drops and recreates all
# database files, installs gems one at a time, generates a systemd unit,
# and adds cron entries to the existing liquidsoap user's crontab.
set -euo pipefail

INSTALL_DIR="$(cd "$(dirname "$0")" && pwd)"
SERVICE_BASENAME="$(basename "${INSTALL_DIR}")"
SERVICE_NAME="${SERVICE_BASENAME}.service"
UNIT_PATH="/etc/systemd/system/${SERVICE_NAME}"

CONFIG_JSON="${INSTALL_DIR}/config.json"
GEMS_DIR="${INSTALL_DIR}/.gems"
JRUBY_BIN=""

echo "=== ${SERVICE_BASENAME} installer ==="
echo

# --- Detect JRuby -----------------------------------------------------------
if command -v jruby >/dev/null 2>&1; then
    JRUBY_BIN="$(command -v jruby)"
elif [ -x /opt/jruby/bin/jruby ]; then
    JRUBY_BIN="/opt/jruby/bin/jruby"
else
    echo "ERROR: jruby not found on PATH or at /opt/jruby/bin/jruby." >&2
    exit 1
fi
echo "==> Using JRuby: ${JRUBY_BIN}"
echo

# --- Prompt for storage root ------------------------------------------------
STORAGE_ROOT_DEFAULT="/mnt/storage/radio"
printf "Storage root [%s]: " "${STORAGE_ROOT_DEFAULT}"
read -r STORAGE_ROOT_INPUT
STORAGE_ROOT="${STORAGE_ROOT_INPUT:-${STORAGE_ROOT_DEFAULT}}"
echo "==> Storage root: ${STORAGE_ROOT}"

# --- Create media and state directories -------------------------------------
for d in music podcasts jingles announcements state logs; do
    mkdir -p "${STORAGE_ROOT}/${d}"
done
chown -R liquidsoap:liquidsoap "${STORAGE_ROOT}" 2>/dev/null || true
echo "==> Media/state/log directories created under ${STORAGE_ROOT}"

# --- Drop and recreate databases --------------------------------------------
rm -f "${STORAGE_ROOT}/state/subscriptions.db" \
      "${STORAGE_ROOT}/state/played.db" \
      "${STORAGE_ROOT}/state/subscriptions.db-wal" \
      "${STORAGE_ROOT}/state/subscriptions.db-shm" \
      "${STORAGE_ROOT}/state/played.db-wal" \
      "${STORAGE_ROOT}/state/played.db-shm"
echo "==> Databases dropped (will be recreated now)"
# Initialize database schemas
sqlite3 "${STORAGE_ROOT}/state/subscriptions.db" <<'SQL'
CREATE TABLE IF NOT EXISTS shows (
    guid TEXT PRIMARY KEY,
    slug TEXT UNIQUE NOT NULL,
    title TEXT,
    feed_url TEXT UNIQUE NOT NULL,
    archive INTEGER DEFAULT 0,
    opml_import INTEGER DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
SQL

sqlite3 "${STORAGE_ROOT}/state/played.db" <<'SQL'
CREATE TABLE IF NOT EXISTS episodes (
    guid TEXT PRIMARY KEY,
    show_guid TEXT NOT NULL REFERENCES shows(guid),
    title TEXT,
    url TEXT,
    duration_seconds INTEGER,
    played INTEGER DEFAULT 0,
    local_path TEXT,
    file_size_bytes INTEGER DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
SQL

echo "Database schemas initialized."

# --- Install gems one at a time ---------------------------------------------
export GEM_HOME="${GEMS_DIR}"
export GEM_PATH="${GEMS_DIR}"
mkdir -p "${GEMS_DIR}"

for gem_name in sequel jdbc-sqlite3 json nokogiri; do
    echo "==> Installing gem: ${gem_name}"
    if ! "${JRUBY_BIN}" -S gem install --local "${gem_name}" 2>/dev/null; then
        "${JRUBY_BIN}" -S gem install "${gem_name}"
    fi
done

# --- Write complete config.json ----------------------------------------------
ICECAST_HOST_DEFAULT="192.168.0.200"
ICECAST_PORT_DEFAULT="7777"
ICECAST_MOUNT_DEFAULT="/data"
ICECAST_SOURCE_USER_DEFAULT="source"
GPODDER_ENABLE_DEFAULT="false"
GPODDER_HOST_DEFAULT="gpodder.net"

printf "Icecast host [%s]: " "${ICECAST_HOST_DEFAULT}"
read -r ICECAST_HOST_INPUT; ICECAST_HOST="${ICECAST_HOST_INPUT:-${ICECAST_HOST_DEFAULT}}"
printf "Icecast source port [%s]: " "${ICECAST_PORT_DEFAULT}"
read -r ICECAST_PORT_INPUT; ICECAST_PORT="${ICECAST_PORT_INPUT:-${ICECAST_PORT_DEFAULT}}"
printf "Mount point [%s]: " "${ICECAST_MOUNT_DEFAULT}"
read -r ICECAST_MOUNT_INPUT; ICECAST_MOUNT="${ICECAST_MOUNT_INPUT:-${ICECAST_MOUNT_DEFAULT}}"
printf "Source username [%s]: " "${ICECAST_SOURCE_USER_DEFAULT}"
read -r ICECAST_SRC_USER_INPUT; ICECAST_SRC_USER="${ICECAST_SRC_USER_INPUT:-${ICECAST_SOURCE_USER_DEFAULT}}"
printf "Source password: "
read -rs ICECAST_SRC_PASS
echo
printf "gPodder sync enabled? (y/n) [n]: "
read -r GP_SYNC_INPUT
case "${GP_SYNC_INPUT,,}" in
    y|yes) GP_ENABLED=true ;;
    *)     GP_ENABLED=false ;;
esac
GP_HOST="${GPODDER_HOST_DEFAULT}"
GP_USERNAME=""
GP_PASSWORD=""
GP_DEVICE_ID=""
if [ "${GP_ENABLED}" = "true" ]; then
    printf "gPodder username: "
    read -r GP_USERNAME
    printf "gPodder password: "
    read -rs GP_PASSWORD
    echo
    printf "gPodder device ID (leave blank to generate): "
    read -r GP_DEVICE_ID
    if [ -z "${GP_DEVICE_ID}" ]; then
        GP_DEVICE_ID="radio-$(date +%s)-$$"
    fi
fi

cat > "${CONFIG_JSON}" <<EOF
{
  "storage": "${STORAGE_ROOT}",
  "icecast": {
    "host": "${ICECAST_HOST}",
    "port": ${ICECAST_PORT},
    "mount": "${ICECAST_MOUNT}",
    "source_username": "${ICECAST_SRC_USER}",
    "source_password": "${ICECAST_SRC_PASS}"
  },
  "gpodder": {
    "enable": ${GP_ENABLED},
    "host": "${GP_HOST}",
    "username": "${GP_USERNAME}",
    "password": "${GP_PASSWORD}",
    "device_id": "${GP_DEVICE_ID}"
  }
}
EOF
chmod 600 "${CONFIG_JSON}"
echo "==> Wrote ${CONFIG_JSON}"

# --- Generate systemd unit ----------------------------------------------------
cat > "${UNIT_PATH}" <<EOF
[Unit]
Description=${SERVICE_BASENAME} (JRuby radio automation)
After=network-online.target sound.target
Wants=network-online.target

[Service]
Type=simple
User=liquidsoap
WorkingDirectory=${INSTALL_DIR}
Environment=GEM_HOME=${GEMS_DIR}
Environment=GEM_PATH=${GEMS_DIR}
ExecStart=${JRUBY_BIN} ${INSTALL_DIR}/station.rb
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
echo "==> Installed ${UNIT_PATH}"
# After the mkdir -p "$STORAGE/state" line, add:
mkdir -p "$STORAGE_ROOT/state"
chown -R liquidsoap:liquidsoap "$STORAGE_ROOT/state"
chmod 755 "$STORAGE_ROOT/state"
chmod 664 "$STORAGE_ROOT/state/"*.db 2>/dev/null || true

# --- Cron entries (liquidsoap user's crontab already exists from package) -----
CRON_FETCH="0 * * * * cd ${INSTALL_DIR} && ${INSTALL_DIR}/run_radio.sh fetch_podcasts.rb --fetch-all >> ${STORAGE_ROOT}/logs/fetch_cron.log 2>&1"
CRON_UPDATE="30 * * * * cd ${INSTALL_DIR} && ${INSTALL_DIR}/run_radio.sh update_playlist.rb >> ${STORAGE_ROOT}/logs/update_cron.log 2>&1"

CURRENT_CRONTAB=$(crontab -u liquidsoap -l 2>/dev/null || true)
NEW_CRONTAB="${CURRENT_CRONTAB}"
if ! echo "${NEW_CRONTAB}" | grep -qF "fetch_podcasts.rb --fetch-all"; then
    NEW_CRONTAB="${NEW_CRONTAB}${NEW_CRONTAB:+$'\n'}${CRON_FETCH}"
fi
if ! echo "${NEW_CRONTAB}" | grep -qF "update_playlist.rb"; then
    NEW_CRONTAB="${NEW_CRONTAB}${NEW_CRONTAB:+$'\n'}${CRON_UPDATE}"
fi
echo "${NEW_CRONTAB}" | crontab -u liquidsoap -
echo "==> Cron entries installed for user liquidsoap"

echo
echo "==> Done. Review ${CONFIG_JSON}, then:"
echo "    systemctl start ${SERVICE_NAME}"

