#!/usr/bin/env bash
# install_for_python - Radio automation installer for Linux Mint 22.3
#
# Installs the liquidsoap-based radio automation stack:
#   - Creates the 'liquidsoap' system user
#   - Prompts for storage path, Icecast credentials, gpodder.net credentials
#   - Generates config.json from the answers
#   - Sets up directory structure under <storage>/
#   - Ensures SQLite databases exist with correct schema
#   - Installs JRuby gems (sequel, jdbc-sqlite3, nokogiri, json) one at a time
#   - Writes the self-locating run_radio.sh launcher
#   - Installs crontab entries (as liquidsoap) for periodic fetch + update
#   - Optionally enables the systemd service
#
# Usage: sudo ./install_for_python
set -euo pipefail

# ---------------------------------------------------------------------------
# Derive service name from containing directory name
# ---------------------------------------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_NAME="$(basename "$SCRIPT_DIR")"
SYSTEMD_UNIT="/etc/systemd/system/${SERVICE_NAME}.service"

echo "=== ${SERVICE_NAME} Installer ==="
echo

# ---------------------------------------------------------------------------
# Root check
# ---------------------------------------------------------------------------
if [[ $EUID -ne 0 ]]; then
  echo "ERROR: Please run as root (sudo)." >&2
  exit 1
fi

# ---------------------------------------------------------------------------
# Create liquidsoap system user if missing
# ---------------------------------------------------------------------------
if ! id -u liquidsoap >/dev/null 2>&1; then
  echo "Creating system user 'liquidsoap'..."
  useradd --system --create-home --shell /usr/sbin/nologin liquidsoap
  echo "Done."
else
  echo "User 'liquidsoap' already exists."
fi

# ---------------------------------------------------------------------------
# Prompt for configuration values
# ---------------------------------------------------------------------------
echo
read -rp "Station data directory [/mnt/storage/radio]: " STORAGE
STORAGE="${STORAGE:-/mnt/storage/radio}"

read -rp "Icecast host [192.168.0.200]: " ICECAST_HOST
ICECAST_HOST="${ICECAST_HOST:-192.168.0.200}"

read -rp "Icecast source port [7777]: " ICECAST_PORT
ICECAST_PORT="${ICECAST_PORT:-7777}"

read -rp "Icecast mount point [/data]: " ICECAST_MOUNT
ICECAST_MOUNT="${ICECAST_MOUNT:-/data}"

read -rp "Icecast source username [source]: " SOURCE_USER
SOURCE_USER="${SOURCE_USER:-source}"

read -rsp "Icecast source password: " SOURCE_PASS
echo

GPODDER_ENABLE=""
until [[ "$GPODDER_ENABLE" =~ ^[YyNn]$ ]]; do
  read -rp "Enable gPodder.net sync? [y/N]: " GPODDER_ENABLE
done
GPODDER_ENABLED=false
[[ "$GPODDER_ENABLE" =~ ^[Yy]$ ]] && GPODDER_ENABLED=true

GPODDER_HOST="gpodder.net"
GPODDER_USER=""
GPODDER_PASS=""
if [[ "$GPODDER_ENABLED" == true ]]; then
  read -rp "gPodder.net host [gpodder.net]: " GPODDER_HOST_IN
  GPODDER_HOST="${GPODDER_HOST_IN:-gpodder.net}"
  read -rp "gPodder.net username: " GPODDER_USER
  read -rsp "gPodder.net password: " GPODDER_PASS
  echo
fi

# ---------------------------------------------------------------------------
# Create directory structure
# ---------------------------------------------------------------------------
echo
echo "Creating directory structure under ${STORAGE} ..."
mkdir -p "${STORAGE}"/{state,podcasts,music,jingles,announcements,playlists,logs}
chown -R liquidsoap:liquidsoap "${STORAGE}"
chmod -R u+rwX,g+rwX,o+rX "${STORAGE}"
echo "Done."

# ---------------------------------------------------------------------------
# Generate config.json
# ---------------------------------------------------------------------------
CONFIG_FILE="${SCRIPT_DIR}/config.json"
cat > "$CONFIG_FILE" <<EOF
{
  "storage": "${STORAGE}",
  "icecast": {
    "host": "${ICECAST_HOST}",
    "port": ${ICECAST_PORT},
    "mount": "${ICECAST_MOUNT}",
    "source_username": "${SOURCE_USER}",
    "source_password": "${SOURCE_PASS}"
  },
  "gpodder": {
    "enable": ${GPODDER_ENABLED},
    "host": "https://${GPODDER_HOST}",
    "username": "${GPODDER_USER}",
    "password": "${GPODDER_PASS}"
  }
}
EOF
chown liquidsoap:liquidsoap "$CONFIG_FILE"
chmod 640 "$CONFIG_FILE"
echo "Wrote ${CONFIG_FILE}"

# ---------------------------------------------------------------------------
# Ensure SQLite databases exist with correct schema
# ---------------------------------------------------------------------------
STATE_DIR="${STORAGE}/state"
SUBS_DB="${STATE_DIR}/subscriptions.db"
PLAYED_DB="${STATE_DIR}/played.db"

ensure_schema() {
  local db="$1" table_sql="$2" index_sql="$3"
  sqlite3 "$db" <<<"$table_sql"
  [[ -n "$index_sql" ]] && sqlite3 "$db" <<<"$index_sql"
  sqlite3 "$db" "PRAGMA journal_mode=WAL;"
}

SHOWS_SQL='CREATE TABLE IF NOT EXISTS shows (
  slug        TEXT PRIMARY KEY,
  guid        TEXT NOT NULL UNIQUE,
  name        TEXT NOT NULL,
  feed_url    TEXT NOT NULL UNIQUE,
  source      TEXT DEFAULT '"'"'manual'"'"',
  opml_import INTEGER DEFAULT 0,
  archived    INTEGER DEFAULT 1,
  media_class TEXT,
  created_at  TEXT
);'

EPISODES_SQL='CREATE TABLE IF NOT EXISTS episodes (
  id            INTEGER PRIMARY KEY AUTOINCREMENT,
  show_slug     TEXT NOT NULL,
  guid          TEXT NOT NULL,
  title         TEXT,
  file_path     TEXT,
  enclosure_url TEXT,
  runlength     INTEGER,
  played        INTEGER DEFAULT 0,
  played_at     TEXT,
  UNIQUE (show_slug, guid)
);'

INDEX_EPISODES_SQL='CREATE INDEX IF NOT EXISTS idx_episodes_show_played ON episodes (show_slug, played);'

echo
echo "Initializing SQLite databases..."
ensure_schema "$SUBS_DB"   "$SHOWS_SQL"   ""
ensure_schema "$PLAYED_DB" "$EPISODES_SQL" "$INDEX_EPISODES_SQL"
chown liquidsoap:liquidsoap "$SUBS_DB" "$PLAYED_DB"
echo "Done."

# ---------------------------------------------------------------------------
# Install JRuby runtime dependencies (one gem per command to bound memory)
# ---------------------------------------------------------------------------
JRUBY_BIN="/opt/jruby/bin/jruby"
GEM_BIN="/opt/jruby/bin/gem"
GEMS_HOME="${SCRIPT_DIR}/.gems"

if [[ -x "$JRUBY_BIN" ]]; then
  echo
  echo "Installing JRuby gem dependencies into ${GEMS_HOME} ..."
  mkdir -p "$GEMS_HOME"
  chown liquidsoap:liquidsoap "$GEMS_HOME"

  install_gem() {
    local gem_name="$1"
    shift
    local extra_args=("$@")
    echo "  -> gem install ${gem_name} ${extra_args[*]}"
    sudo -u liquidsoap bash -c "
      export GEM_HOME=${GEMS_HOME}
      export GEM_PATH=${GEMS_HOME}:/opt/jruby/lib/ruby/gems/shared
      ${GEM_BIN} install ${gem_name} ${extra_args[*]} --no-document
    " || echo "  WARNING: failed to install ${gem_name}"
  }

  # Core persistence
  install_gem "sequel"
  install_gem "jdbc-sqlite3"

  # XML parsing. Pure-Java build under JRuby (--platform java) bundles
  # Xerces/NekoHTML/Xalan as JARs; no libxml2-dev or compiler required.
  install_gem "nokogiri" "--platform" "java"

  # Convenience JSON (usually stdlib, but ensure availability)
  install_gem "json"

  echo "JRUBY DEPENDENCIES COMPLETE"
else
  echo
  echo "WARNING: ${JRUBY_BIN} not found; skipping JRuby gem installation."
  echo "         Install JRuby manually, then re-run this installer or run:"
  echo "           sudo -u liquidsoap ${GEM_BIN} install sequel jdbc-sqlite3 json"
  echo "           sudo -u liquidsoap ${GEM_BIN} install nokogiri --platform java"
fi

# ---------------------------------------------------------------------------
# Self-locating launcher (sets GEM_HOME/GEM_PATH before JRuby boots)
# ---------------------------------------------------------------------------
LAUNCHER="${SCRIPT_DIR}/run_radio.sh"
cat > "$LAUNCHER" <<'LAUNCH_EOF'
#!/usr/bin/env bash
# run_radio.sh - self-locating JRuby launcher for the radio automation scripts.
# Exports GEM_HOME/GEM_PATH BEFORE jruby boots, because mutating them inside a
# running JRuby process does not reliably affect gem resolution (JRuby #5269).
#
# Usage: ./run_radio.sh <script.rb> [args...]
set -euo pipefail

SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GEMS_HOME="${SELF_DIR}/.gems"
JRUBY_HOME="/opt/jruby"

export GEM_HOME="${GEMS_HOME}"
export GEM_PATH="${GEMS_HOME}:${JRUBY_HOME}/lib/ruby/gems/shared"

exec "${JRUBY_HOME}/bin/jruby" "${SELF_DIR}/$@"
LAUNCH_EOF
chmod +x "$LAUNCHER"
chown liquidsoap:liquidsoap "$LAUNCHER"
echo "Wrote ${LAUNCHER}"

# Make the Ruby scripts executable
for rb in "${SCRIPT_DIR}"/*.rb; do
  [[ -f "$rb" ]] && chmod +x "$rb" && chown liquidsoap:liquidsoap "$rb"
done

# ---------------------------------------------------------------------------
# Crontab entries (installed into liquidsoap's crontab, not root's)
# ---------------------------------------------------------------------------
CRON_FETCH="*/30 * * * * cd ${SCRIPT_DIR} && ./run_radio.sh fetch_podcasts.rb >> ${STORAGE}/logs/cron_fetch.log 2>&1"
CRON_UPDATE="15 * * * * cd ${SCRIPT_DIR} && ./run_radio.sh update_playlists.rb >> ${STORAGE}/logs/cron_update.log 2>&1"

echo
echo "Installing crontab entries for user 'liquidsoap'..."
( crontab -l -u liquidsoap 2>/dev/null || true ) | grep -vF "run_radio.sh" | \
  { cat; echo "$CRON_FETCH"; echo "$CRON_UPDATE"; } | crontab -u liquidsoap -
echo "Crontab updated."

# ---------------------------------------------------------------------------
# Optional systemd service
# ---------------------------------------------------------------------------
ENABLE_SERVICE=""
until [[ "$ENABLE_SERVICE" =~ ^[YyNn]$ ]]; do
  read -rp "Enable ${SERVICE_NAME} systemd service now? [y/N]: " ENABLE_SERVICE
done

if [[ "$ENABLE_SERVICE" =~ ^[Yy]$ ]]; then
  echo
  echo "Writing ${SYSTEMD_UNIT} ..."
  cat > "$SYSTEMD_UNIT" <<UNIT_EOF
[Unit]
Description=${SERVICE_NAME} radio automation (liquidsoap)
After=network-online.target icecast2.service
Wants=network-online.target

[Service]
Type=simple
User=liquidsoap
WorkingDirectory=${SCRIPT_DIR}
ExecStart=${SCRIPT_DIR}/station.liq
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
UNIT_EOF

  systemctl daemon-reload
  systemctl enable --now "${SERVICE_NAME}"
  echo "Service ${SERVICE_NAME} enabled and started."
else
  echo "Skipping systemd service (you can enable it later with:"
  echo "  sudo cp ${SCRIPT_DIR}/${SERVICE_NAME}.service /etc/systemd/system/ && sudo systemctl enable --now ${SERVICE_NAME})"
fi

# ---------------------------------------------------------------------------
# Summary
# ---------------------------------------------------------------------------
echo
echo "=============================================="
echo " Installation complete."
echo "----------------------------------------------"
echo " Storage:      ${STORAGE}"
echo " Config:       ${CONFIG_FILE}"
echo " Launcher:     ${LAUNCHER}"
echo " Service:      ${SERVICE_NAME}"
echo "----------------------------------------------"
echo " Quick start:"
echo "   cd ${SCRIPT_DIR}"
echo "   sudo -u liquidsoap ./run_radio.sh fetch_podcasts.rb --list-shows"
echo "   sudo -u liquidsoap ./run_radio.sh fetch_podcasts.rb --add-show <rss-url>"
echo "   sudo -u liquidsoap ./run_radio.sh update_playlists.rb"
echo "=============================================="
